Value_type error when using STL containers with long-range adapters

I tried to understand the use of extended range adapters, but all the working examples I found use only STL containers with primitive types such as std::list<int> , and trying to use my own classes makes everything fall apart.

 #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 ); } 

Using gcc 4.6 / 4.8 and boost 1.48 / 1.54 / trunk, I get the following compilation error:

 /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); 

I understand the problems with decltype and result_of , which can cause a problem with transformed , even though my BOOST_RESULT_OF_USE_DECLTYPE determines how this answer is advised. However, I do not understand why I cannot pass filtered to functor struct or if there are additional requirements for my Thing class.

+4
source share
1 answer

According to the documentation , the first copy argument is a range and the second is an iterator, so changing your call to:

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

does compilation with g ++ 4.8.1 and raises the level of 1.53.0.

+2
source

Source: https://habr.com/ru/post/1490130/


All Articles