在 c++14 lambda 表达式中捕获和移动 unique_ptr
Posted
技术标签:
【中文标题】在 c++14 lambda 表达式中捕获和移动 unique_ptr【英文标题】:Capture and move a unique_ptr in a c++14 lambda expression 【发布时间】:2015-03-04 05:26:35 【问题描述】:我以这种方式在 lambda 表达式中捕获 unique_ptr:
auto str = make_unique<string>("my string");
auto lambda = [ capturedStr = std::move(str) ]
cout << *capturedStr.get() << endl;
;
lambda();
在我尝试将 capturedStr
移动到另一个 unique_ptr 之前,它工作得很好。例如,以下内容不起作用:
auto str = make_unique<string>("my string");
auto lambda = [ capturedStr = std::move(str) ]
cout << *capturedStr.get() << endl;
auto str2 = std::move(capturedStr); // <--- Not working, why?
;
lambda();
这是编译器的输出:
.../test/main.cpp:11:14: error: call to implicitly-deleted copy
constructor of 'std::__1::unique_ptr<std::__1::basic_string<char>,
std::__1::default_delete<std::__1::basic_string<char> > >'
auto str2 = std::move(capturedStr);
^ ~~~~~~~~~~~~~~~~~~~~~~ ../include/c++/v1/memory:2510:31: note: copy constructor is implicitly
deleted because 'unique_ptr<std::__1::basic_string<char>,
std::__1::default_delete<std::__1::basic_string<char> > >' has a
user-declared move constructor
_LIBCPP_INLINE_VISIBILITY unique_ptr(unique_ptr&& __u) _NOEXCEPT
^ 1 error generated.
为什么不能移动capturedStr
?
【问题讨论】:
Lambdas'operator ()
是 const
,除非它被声明为 mutable
,并且你不能从 const
对象中移动。
谢谢@T.C.,你能写一个答案吗,我会接受的
【参考方案1】:
lambda 的operator ()
默认为const
,您不能从const
对象移动。
如果要修改捕获的变量,请声明mutable
。
auto lambda = [ capturedStr = std::move(str) ] () mutable
// ^^^^^^^^^^
cout << *capturedStr.get() << endl;
auto str2 = std::move(capturedStr);
;
【讨论】:
我以为你不会发帖 :) +1【参考方案2】:auto lambda = [ capturedStr = std::move(str) ]
cout << *capturedStr.get() << endl;
auto str2 = std::move(capturedStr); // <--- Not working, why?
;
为了提供更多细节,编译器正在有效地进行这种转换:
class NameUpToCompiler
unique_ptr<string> capturedStr; // initialized from move assignment in lambda capture expression
void operator()() const
cout << *capturedStr.get() << endl;
auto str2 = std::move(capturedStr); // move will alter member 'captureStr' but can't because of const member function.
在 lambda 上使用 mutable 将从 operator() 成员函数中删除 const,因此允许更改成员。
【讨论】:
【参考方案3】:为了使建议更明确:添加mutable
:http://coliru.stacked-crooked.com/a/a19897451b82cbbb
#include <memory>
int main()
std::unique_ptr<int> pi(new int(42));
auto ll = [ capturedInt = std::move(pi) ] () mutable ;
【讨论】:
以上是关于在 c++14 lambda 表达式中捕获和移动 unique_ptr的主要内容,如果未能解决你的问题,请参考以下文章