Say I have
class Value;
class Key;
class MyClass {
private:
std::map<Key,Value> my_map;
....
}
Inside of MyClass methods I have a very convenient way to iterate through values of my_map by saying
for( auto& value: my_map | boost::adaptors::map_values) {
...
}
However I would like to have a method of MyClass that would essentially output my_map | boost::adaptors::map_values and allow convenient value iteration outside of MyClass methods. How do I declare such a method? Would I need to implement some sort of pseudo container and corresponding iterator or there is a shortcut?
Basically, you have two good choices. You can provide users with a nicely decoupled interface by using boost's any_range
, or else if you need the best performance, you can give clients direct access to the adapted range using c++11 decltypes. In the first case, clients won't have to change if you change implementation, but this comes at a cost of extra redirection.
using any_range
:
#include <boost/range.hpp>
#include <map>
#include <boost/range/adaptor/map.hpp>
#include <boost/range/any_range.hpp>
class Foo
{
std::map<int, int> my_map;
boost::any_range<int, boost::forward_traversal_tag, int&, std::ptrdiff_t> Values()
{ return my_map | boost::adaptors::map_values; }
};
giving direct access (awkward syntax here is because you require VS2013, which doesn't support member variables in unevaluated context at class scope):
#include <boost/range.hpp>
#include <map>
#include <boost/range/adaptor/map.hpp>
class Foo
{
std::map<int, int> my_map;
auto Values() -> decltype(my_map | boost::adaptors::map_values)
{ return my_map | boost::adaptors::map_values; }
};