是否可以使用 lambda 初始化变量(删除复制 ctor 时)
Is it possible to initialize variable with lambda (when copy ctor is deleted)?
我有以下代码:
struct A {//<-- Third party library class
A(){};
A(const A&) = delete;
void init(){};
int i;
};
int f(){
static A a = []{
A res;
res.init();
return res;
}();
return a.i;
}
现场观看:http://coliru.stacked-crooked.com/a/a5c5912bd79053c3
编译时会给出以下错误:
g++ -std=c++17 -O2 -Wall -pedantic -pthread main.cpp && ./a.out
main.cpp: In lambda function:
main.cpp:12:12: error: use of deleted function 'A::A(const A&)'
return res;
^~~
main.cpp:4:3: note: declared here
A(const A&) = delete;
^
我知道我可以将其包装在另一个struct
中并在该构造函数中初始化,但这似乎有些乏味。使用 c++17,我们是否有解决这个"问题"的"巧妙"方法?
任何解决方案都必须同样适用于函数中的静态变量
如果您的类不可移动,并且复制构造函数被删除/不可访问,那么您别无选择,只能返回对静态对象的引用或返回指针。 这是因为 C++17 的保证复制省略仅适用于 prvalues。 由于对象在 lambda 中具有名称,因此即使应用 NRVO,也必须能够将其移动或复制到返回对象中。
您可以使用
A& a = []() -> A& {
static A res;
res.init();
return res;
}();
或
auto a = []{
auto res = std::make_unique<A>();
res->init();
return res;
}();
您可以在默认构造函数上调用init
。然后,您可以在静态函数和静态成员函数上执行此操作。也可以在 prvalues 上使用复制省略号并提供类似 A res = []{ return A(); }();
.
#include <iostream>
struct A {//Third party library class
constexpr A() :i{}
{ init(); };
A(const A&) = delete;
constexpr void init(){ i = 5; };
int i;
};
struct A_User {
static constexpr void A_print() {
constexpr A res{};
static_assert(res.i == 5);
}
};
A& static_func() {
static A res{};
std::cout << "res static: " << res.i << "n";
return res;
}
A res = []{ return A(); /* copy elided since this is prvalue */ }();
int main() {
std::cout << "res global: " << res.i << "n";
auto& static_A = static_func();
}
相关文章:
- 为什么在C++中使用私有复制构造函数与删除复制构造函数
- 为什么类中的ostringstream类型的成员会导致";调用隐含删除复制构造函数";错误
- std::ofstream 作为类成员删除复制构造函数?
- 具有已删除移动和复制构造函数的类的就地构造
- 聚合初始化和删除的复制构造函数,也称为不可复制的 obejcts 作为字段
- 我可以从列表中获取对象并复制它们,但如何删除我复制的对象?
- 在引用初始化中使用已删除的复制构造函数进行复制初始化
- std::p ackaged_task 应该删除带有 const 参数的复制 c'tor
- 我什么时候会默认(而不是删除)基类中的复制和移动操作
- 为什么在删除"移动构造函数"时使用"复制构造函数"?
- 调用类模板中隐式删除的复制构造函数
- 为什么基类中的复制和交换会导致派生类中的复制赋值运算符被隐式删除?
- shared_ptr删除器类 - 为什么要复制删除器?
- 复制后删除原始数组指针将前 3 个字节设置为 0
- 删除复制构造函数的 Intel 13.1.2 中不良C++行为的解决方法
- c++:复制、删除和运算符=在原始指针映射中
- c++17在编译时将带有已删除复制构造函数的类添加到std::vector
- Windows Portable设备 - 创建 /复制 /删除新文件时通知
- 复制-删除返回的自动变量
- 列表初始化和复制删除