为什么在移动 `unique_ptr` 时在 lambda 中调用复制构造函数?
Why is the copy constructor invoked in a lambda while moving a `unique_ptr`?
为什么这段代码编译失败?
#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()
as
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
上都试过了,结果相似。那么,有人可以帮助我消除理解上的差距吗?
这是因为您试图在 const
成员函数中移动数据成员。
std::move(s)
的类型和类别是const unique_ptr&&
。没有重载 unique_ptr(const unique_ptr&&)
,唯一可行的是 unique_ptr(const unique_ptr&)
.
I think this would fail to compile because the move(s)
would change the value of s
which isn't allowed in a const
function.
不,move
只是一个 static_cast
。
为什么这段代码编译失败?
#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()
as
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
上都试过了,结果相似。那么,有人可以帮助我消除理解上的差距吗?
这是因为您试图在 const
成员函数中移动数据成员。
std::move(s)
的类型和类别是const unique_ptr&&
。没有重载 unique_ptr(const unique_ptr&&)
,唯一可行的是 unique_ptr(const unique_ptr&)
.
I think this would fail to compile because the
move(s)
would change the value ofs
which isn't allowed in aconst
function.
不,move
只是一个 static_cast
。