Ответ 1
Обновление: вы можете захватить подвижную переменную в lambda с С++ 14 и далее.
std::for_each(arr.begin(), arr.end(), [p=std::move(p)](int& i) { i+=*p; });
Вы не можете зафиксировать подвижную переменную в лямбда любым простым способом в С++ 11.
Захват Lambdas копией или ссылкой. Таким образом, чтобы зафиксировать переменную только для перемещения, вы должны обернуть ее в объект, где копирование = > перемещение (например, std::auto_ptr
). Это неприятный хак.
В вашем примере вы можете просто захватить по ссылке, но если это был просто упрощенный код, он может не делать то, что вы хотели с реальным кодом:
std::for_each(arr.begin(), arr.end(), [&p](int& i) { i+=*p; });
Здесь оболочка copy-move-only:
template<typename T>
struct move_on_copy_wrapper
{
mutable T value;
move_on_copy_wrapper(T&& t):
value(std::move(t))
{}
move_on_copy_wrapper(move_on_copy_wrapper const& other):
value(std::move(other.value))
{}
move_on_copy_wrapper(move_on_copy_wrapper&& other):
value(std::move(other.value))
{}
move_on_copy_wrapper& operator=(move_on_copy_wrapper const& other)
{
value=std::move(other.value);
return *this;
}
move_on_copy_wrapper& operator=(move_on_copy_wrapper&& other)
{
value=std::move(other.value);
return *this;
}
};
Затем вы можете использовать его следующим образом:
int main()
{
std::unique_ptr<int> p(new int(3));
move_on_copy_wrapper<std::unique_ptr<int>> mp(std::move(p));
[mp]()
{
std::cout<<"*mp.value="<<*mp.value<<std::endl;
}
();
std::cout<<"p="<<p.get()<<", mp="<<mp.value.get()<<std::endl;
}