【发布时间】:2021-02-18 15:14:19
【问题描述】:
为什么这段代码编译失败?
#include <memory>
#include <utility>
int foo() {
auto num = std::make_unique<int>(1);
auto func = [s = std::move(num)] {
auto u = std::move(s); <-- ERROR!
return *u;
};
return func();
}
错误是:
<source>:8:14: error: call to deleted constructor of 'std::unique_ptr<int, std::default_delete<int>>'
auto u = std::move(s);
^ ~~~~~~~~~~~~
/opt/compiler-explorer/gcc-10.2.0/lib/gcc/x86_64-linux-gnu/10.2.0/../../../../include/c++/10.2.0/bits/unique_ptr.h:468:7: note: 'unique_ptr' has been explicitly marked deleted here
unique_ptr(const unique_ptr&) = delete;
我不知道为什么要调用复制构造函数,这显然被设计为unique_ptr 删除了。我可以理解什么错误是什么,但不知道为什么它首先存在。
这就是我认为会发生的情况,但我不确定。如果我将这个 lambda 解压成一种 struct 并带有 operator() 作为
template <typename T>
struct Lambda{
:
:
operator() const{
auto u = std::move(s); // <-- error
}
private:
std::unique_ptr<T> s;
};
我认为这将无法编译,因为 move(s) 会更改 s 的值,而这在 const 函数中是不允许的。因此,引用 lamda 的不变性,编译应该失败。甚至可以通过将 lambda 更改为 mutable 来修复此错误。但另一个似乎是让s 成为shared_ptr(根据我的说法,这应该失败,因为 lambda 仍然是不可变的),这就是我感到困惑的地方。
我在clang 和gcc 上都试过这个,结果相似。那么,请有人帮忙消除我的理解上的差距吗?
【问题讨论】:
-
Lambda 捕获,如
s,默认为 const。尝试在{之前添加mutable。 (你的 lambda 也缺少参数列表?) -
好的,如果下面的答案不充分,请告诉我们,我们会进一步澄清。
-
@rustyx 我已经接受了答案。使用
shared_ptr的替代方法有其自身的行为。我已将我的 cmets 更新为以下答案。如果您有其他内容,请添加。
标签: c++ lambda unique-ptr