I am learning the new features in c++11 and came across this problem. I'd like to capture an unique_ptr by moving it inside a lambda as an argument for for_each.
set up:
std::array<int,4> arr = {1,3,5,6};
std::unique_ptr<int> p(new int); (*p) = 3;
attempt 1 - doesn't work because unique_ptr doesn't have a copy constructor. c++0x doesn't specify the pass by move syntax.
std::for_each(arr.begin(), arr.end(), [p](int& i) { i+=*p; });
attempt 2 - use bind to bind a moved copy of p to a function that takes int&:
std::for_each(arr.begin(), arr.end(),
std::bind([](const unique_ptr<int>& p, int& i){
i += (*p);
}, std::move(p))
);
Compiler complains that 'result' : symbol is neither a class template nor a function template.
The main purpose of the exercise is to understand how a movable variable be captured in a lambda that's cached for later use.
Update: you can capture a movable variable in a lambda from C++14 onwards.
You cannot capture a movable variable into a lambda in any straightforward way in C++11.
Lambdas capture by copy or by reference. Thus, to capture a move-only variable, you have to wrap it in an object where copying => moving (such as
std::auto_ptr
). This is a nasty hack.In your example, you can just capture by reference, but if this was just simplified code it may not do what you wanted with the real code:
Here's a copy-move-only wrapper:
You can then use it like this:
Your attempt 2 will almost work.
What's missing is you haven't told your
bind
call to expect a parameter:The
placeholders::_1
is necessary to tell the result ofbind
that it should expect a parameter passed to it for itsoperator()
.This is also the suggestion given in @marton78's answer here.