Bom*_*maz 4 c++ struct initialization c++17 visual-studio-2017
我有一个结构,我想使用初始化列表初始化
struct Parent{};
struct Child : private Parent {
int b;
};
int main() {
Child c{ 1 };
return 0;
}
Run Code Online (Sandbox Code Playgroud)
看看其他问题,我发现这个答案表明它应该可以在c ++ 17中使用.
但是,当我尝试上面的片段时,VS2017我得到了
Error C2440 'initializing': cannot convert from 'initializer list' to 'child'
Run Code Online (Sandbox Code Playgroud)
有没有办法利用这个新功能?
通过继承,聚合的每个基类子对象都像成员一样初始化.所以要聚合初始化,Child有两个子对象:Parent和i.因此,在braced-init-list中需要两个初始值设定项:
Child c{ {}, 1 };
Run Code Online (Sandbox Code Playgroud)
此外,为了Child成为聚合,所有子对象必须是公共的.所以你不能拥有私人基类.
当然,这假设Visual Studio正确实现了该功能.VS2017 15.5不符合C++ 17,但15.7支持此功能.
c++17引入了聚合初始化扩展 (P0017R1),它提供了派生实例的构造,同时仍显式初始化基类:
struct base { int a1, a2; };
struct derived : base { int b1; };
derived d1{{1, 2}, 3}; // full explicit initialization
derived d1{{}, 1}; // the base is value initialized
Run Code Online (Sandbox Code Playgroud)
因此,使用“聚合初始化扩展”,您将需要使用以下代码:Child c{ {}, 1 }正如Nicol Bolas 的回答中再次提到的,他警告您根本public 不需要 private使用继承来进行聚合初始化。
不幸的是,Visual-studio-2017直到版本 15.7 才支持 P0017R1 。因此,可能需要升级 Visual Studio 才能实现此目的。
如果这是不可能的,并且您可以在没有多态性的情况下完成,您可以临时定义:
struct Child {
Parent a;
int b;
};
Run Code Online (Sandbox Code Playgroud)
这将允许您使用一致的代码:Child c{ {}, 1 }现在以及升级到 15.7 后更改回继承时。