2013-07-07 3 views
4

Я пытался понять использование адаптеров диапазона форсирования, но все рабочие примеры, которые я нашел, используют только контейнеры STL с примитивными типами, такими как std::list<int> и пытающиеся использовать мои собственные классы все разваливаются.ошибка value_type при использовании контейнеров STL с адаптерами дальнего радиуса действия

#define BOOST_RESULT_OF_USE_DECLTYPE 
#include <iostream> 
#include <string> 
#include <vector> 
#include <algorithm> 
#include <functional> 
#include <boost/range/adaptors.hpp> 
#include <boost/range/adaptor/transformed.hpp> 
#include <boost/range/adaptor/filtered.hpp> 
#include <boost/range/algorithm.hpp> 

struct Thing 
{ 
    Thing() : _id(0), _name(""){} 
    std::size_t _id; 
    std::string _name; 
}; 

int main() 
{ 
    std::vector<Thing> input; 
    std::vector<Thing> output; 
    std::function<Thing (Thing&)> transform([](Thing& t)->Thing{ 
    t._name = "changed"; 
    return t;}); 

    struct Filter 
    { 
    typedef bool result_type; 
    typedef const Thing& argument_type; 
    result_type operator()(const Thing& t) 
    { 
     return t._id > 1; 
    } 
    }; 
    Filter filter; 

    boost::copy(input 
     | boost::adaptors::filtered(filter) 
     | boost::adaptors::transformed(transform) 
     | boost::adaptors::reversed, 
     output 
    ); 
} 

Использование НКУ 4,6/4,8 и повысить 1,48/1,54/багажник я получаю следующее Ошибка компиляции:

/usr/include/c++/4.8/bits/stl_algobase.h:382:57: error: no type named ‘value_type’ in ‘struct std::iterator_traits<std::vector<Thing> >’ 
     typedef typename iterator_traits<_OI>::value_type _ValueTypeO; 
                 ^
/usr/include/c++/4.8/bits/stl_algobase.h:387:9: error: no type named ‘value_type’ in ‘struct std::iterator_traits<std::vector<Thing> >’ 
     && __are_same<_ValueTypeI, _ValueTypeO>::__value); 

Я понимаю, проблемы с decltype и result_of, которые могут вызвать проблемы с transformed, несмотря на мои BOOST_RESULT_OF_USE_DECLTYPE определите, как вам ответили this. Однако я не понимаю, почему я не могу передать в functor struct значение filtered или если есть дополнительные требования к моему классу Thing.

+1

К сожалению, cv_and_he является абсолютно правильным. Теперь я вижу, что другая разница между моим кодом и [примерной документацией] (http://www.boost.org/doc/libs/1_53_0/libs/range/doc/html/range/reference/adaptors/introduction.html) является использование 'std :: ostream_iterator'. Это может быть вопросом вкуса, но я думаю, что теперь я предпочитаю использовать 'boost :: push_back' для этого, так как в этой области, похоже, есть достаточно функций-оболочек, которые уже рекомендуются с использованием' std :: cref'. – sjdowling

ответ

2

Согласно the documentation первый аргумент copy является диапазон и второй итератор, поэтому изменение вашего розарий:

boost::copy(input 
    | boost::adaptors::filtered(filter) 
    | boost::adaptors::transformed(transform) 
    | boost::adaptors::reversed, 
    std::back_inserter(output) 
); 

делает его компилироваться с г ++ 4.8.1 и увеличить 1.53.0.