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