英文:
Can't use { } initialization in C++20, but in C++17
问题
我有以下的代码:
#include <iostream>
#include <optional>
class Test
{
public:
Test() = delete;
Test& operator=(const Test&) = delete;
Test& operator=(Test&&) = delete;
Test(const Test&) = delete;
Test(Test&&) = delete;
};
int main()
{
Test test{};
}
这段代码大多数情况下可以使用各种编译器(gcc 和 clang)编译,并且程序成功终止。我的问题是对象 Test 是如何构造的,哪个构造函数被调用了?
在这个链接 https://www.onlinegdb.com/online_c++_compiler 中,当选择 C++20 作为标准时,编译失败,但选择 C++17 时,代码可以编译。
英文:
I have the following code :
#include <iostream>
#include <optional>
class Test
{
public:
Test() = delete;
Test& operator=(const Test&) = delete;
Test& operator=(Test&&) = delete;
Test(const Test&) = delete;
Test(Test&&) = delete;
};
int main()
{
Test test{};
}
This code mostly is compiled with various compilers (gcc and clang) and the program is terminated successfully. My question here is how the object Test is constructed. which constructor is called?
Here <https://www.onlinegdb.com/online_c++_compiler> With C++20 selected as the std the compilation fails but with 17 the code compiles.
答案1
得分: 4
你在这里使用了直接列表初始化来初始化 test
。鉴于你的对象的性质,这实际上执行了聚合初始化。由于初始化列表为空,聚合初始化不会执行任何操作。
因此,对于 test
没有调用任何构造函数。
评论中的编辑
自C++20起,如果一个类有一个已删除的构造函数,它不再是一个聚合类,因为构造函数是用户声明的,而在C++17中,为了防止类被视为聚合类,构造函数需要是用户提供的。这就是为什么这段代码在C++17中有效但在C++20中无效的原因。
英文:
You are using a direct list initialization to initialize test
here. Which in turn, given the nature of your object, does an aggregate initialization. The aggregate initialization does nothing, since the initializer list is empty.
So no constructor is called for test
.
EDIT from the comments
Since C++20, if a class has a deleted constructor it is no longer an aggregate because the constructor is user-declared, while in C++17 the constructor needed to be user-provided to prevent the class to be considered an aggregate. This is why the code is valid in C++17 but ill-formed in C++20.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论