捕获 lambda 并移动可赋值
Capturing lambda and move assignable
我很困惑为什么捕获的 lambda 不是可移动赋值的,但它的手动定义(作为带有 operator() 的结构)是。
考虑以下简化代码:
struct Environment {
Environment(std::unique_ptr<int>&& p): ptr(std::move(p)) {}
std::unique_ptr<int> ptr;
};
class LambdaCPPInsights
{
public:
inline /*constexpr */ void operator()() const
{
}
private:
std::shared_ptr<Environment> env;
public:
LambdaCPPInsights(const std::shared_ptr<Environment> & _env)
: env{_env}
{}
};
constexpr const char* btos(bool b)
{
return b ? "true" : "false";
}
int main()
{
auto env = std::make_shared<Environment>(std::make_unique<int>(4));
std::cout << "True lambda is move-assignable: " << btos(std::is_move_assignable_v< decltype([env = env]() {}) >) << std::endl;
std::cout << "Manual lambda is move-assignable: " << btos(std::is_move_assignable_v< LambdaCPPInsights >);
return 0;
}
class LambdaCPPInsights 是 cpp insights 给出的翻译(然后重命名)lambda 结构,因此应该与 [env = env]() {}
定义的 lambda 相同。
但是之前的代码在gcc 11.2和c++20下的输出是:
True lambda is move-assignable: false
Manual lambda is move-assignable: true
godbolt 的例子可以在这里找到:https://godbolt.org/z/Yx3n9eGj5
我错过了什么?
带有捕获的 lambda 具有删除的复制赋值运算符,这也意味着它没有隐式移动赋值运算符。参见 [expr.prim.lambda.closure]/13。
您的 LambdaCPPInsights
没有正确重现闭包类型。它应该显式默认复制和移动构造函数,并显式删除复制赋值运算符。
我很困惑为什么捕获的 lambda 不是可移动赋值的,但它的手动定义(作为带有 operator() 的结构)是。
考虑以下简化代码:
struct Environment {
Environment(std::unique_ptr<int>&& p): ptr(std::move(p)) {}
std::unique_ptr<int> ptr;
};
class LambdaCPPInsights
{
public:
inline /*constexpr */ void operator()() const
{
}
private:
std::shared_ptr<Environment> env;
public:
LambdaCPPInsights(const std::shared_ptr<Environment> & _env)
: env{_env}
{}
};
constexpr const char* btos(bool b)
{
return b ? "true" : "false";
}
int main()
{
auto env = std::make_shared<Environment>(std::make_unique<int>(4));
std::cout << "True lambda is move-assignable: " << btos(std::is_move_assignable_v< decltype([env = env]() {}) >) << std::endl;
std::cout << "Manual lambda is move-assignable: " << btos(std::is_move_assignable_v< LambdaCPPInsights >);
return 0;
}
class LambdaCPPInsights 是 cpp insights 给出的翻译(然后重命名)lambda 结构,因此应该与 [env = env]() {}
定义的 lambda 相同。
但是之前的代码在gcc 11.2和c++20下的输出是:
True lambda is move-assignable: false
Manual lambda is move-assignable: true
godbolt 的例子可以在这里找到:https://godbolt.org/z/Yx3n9eGj5
我错过了什么?
带有捕获的 lambda 具有删除的复制赋值运算符,这也意味着它没有隐式移动赋值运算符。参见 [expr.prim.lambda.closure]/13。
您的 LambdaCPPInsights
没有正确重现闭包类型。它应该显式默认复制和移动构造函数,并显式删除复制赋值运算符。