我正在将C ++ Visual Studio项目从VS2017迁移到VS2019。
我现在遇到一个错误,以前没有发生过,可以通过以下几行代码来重现:
struct Foo
{
Foo() = default;
int bar;
};
auto test = Foo { 0 };
Run Code Online (Sandbox Code Playgroud)
错误是
(6):错误C2440:“正在初始化”:无法从“初始化列表”转换为“ Foo”
(6):注意:没有构造函数可以采用源类型,或者构造函数重载解析度不明确
该项目用/std:c++latest标志编译。我把它复制在了哥德螺栓上。如果我将其切换到/std:c++17,它可以像以前一样正常编译。
我试图用clang编译相同的代码,-std=c++2a并得到了类似的错误。同样,默认或删除其他构造函数也会产生此错误。
显然,VS2019中添加了一些新的C ++ 20功能,我假设在https://en.cppreference.com/w/cpp/language/aggregate_initialization中描述了此问题的起源。在那里,它表示一个聚合可以是(除其他条件外)具有的结构
请注意,括号中的部分“明确允许使用默认或删除的构造函数”已删除,并且“用户提供”更改为“用户声明”。
因此,我的第一个问题是,我是否假设标准的这种更改是我的代码以前编译但现在不再编译的原因?
当然,解决此问题很容易:只需删除显式默认的构造函数即可。
但是,我已经在所有项目中明确地默认并删除了很多构造函数,因为我发现以这种方式使代码更具表现力是一个好习惯,因为与隐式默认或删除的构造函数相比,这样做只会带来更少的惊喜。但是,通过这种更改,这似乎不再是一个好习惯了...
所以我的实际问题是: 从C ++ 17到C ++ 20的变化背后的原因是什么?向后兼容的突破是故意的吗?是否有一些折衷办法,例如“确定,我们在这里破坏了向后兼容性,但这是为了更大的利益。”吗?这个更大的好处是什么?