I have the following simple example, in which I want to call std::for_each on a collection of objects that are non-copyable:
class A {
public:
A() : x(0) {}
A(const A&) = delete;
private:
int x;
};
void func() {
std::vector<A> v(10);
std::map<int, A> m;
// works as expected
std::for_each(begin(v), end(v), [](const A& a) { /* do nothing */ });
// error calling copy constructor
std::for_each(begin(m), end(m), [](const std::pair<int, A>& a) { /* do nothing */ });
}
If I put everything into a std::vector, it works as I expected, but when using a std::map, suddenly std::for_each wants to call the (deleted) copy constructor. Why? I would have assumed that I simply get a reference to the pair that is saved in the map, without any necessary copies.
The problem is that std::map has a std::pair<const Key, Value> as its internal value type. Rather than explicitly specifying this, Standard Library containers allow you to extract this from the container type:
In C++11 do (same as in C++98, but you would have to use a function object rather than a lambda inside for_each, and also use typedef instead of using =):
using value_type = std::map<int, A>::value_type;
std::for_each(begin(m), end(m), [](value_type const& a) { /* do nothing */ });
In C++14 do:
std::for_each(begin(m), end(m), [](auto const& a) { /* do nothing */ });
The use of auto inside the lambda is supported by Clang 3.4, Visual Studio 2013 November CTP, and GCC 4.9.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With