我有一个结构,我想使用初始化列表
进行初始化struct Parent{};
struct Child : private Parent {
int b;
};
int main() {
Child c{ 1 };
return 0;
}
查看其他问题,我发现this answer表明它应该可以在c ++ 17中使用。
然而,当我在VS2017
中尝试上述代码段时,我得到了
Error C2440 'initializing': cannot convert from 'initializer list' to 'child'
有没有办法利用这个新功能?
答案 0 :(得分:8)
使用继承,聚合的每个基类子对象都像成员一样初始化。因此,为了聚合初始化,Child
有两个子对象:Parent
和i
。因此,在braced-init-list中需要两个初始值设定项:
Child c{ {}, 1 };
此外,为了使Child
成为聚合,所有子对象必须 public 。所以你不能拥有私人基类。
当然,这假设Visual Studio正确实现了该功能。 VS2017 15.5不符合C ++ 17,但15.7支持此功能。
答案 1 :(得分:0)
c++14引入了Extension to Aggregate Initialization(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
因此,使用“扩展集初始化初始化”,您将想要使用代码:Nicol Bolas's answer中再次提到的Child c{ {}, 1 }
和他的警告,您需要使用public
not private
继承完全可以进行聚合初始化。
很遗憾,visual-studio-2017不支持P0017R1 until version 15.7。因此,可能需要升级Visual Studio来完成此任务。
如果这是不可能的,并且您无需多态性就可以解决问题,则可以临时定义:
struct Child {
Parent a;
int b;
};
您现在可以使用以下哪个一致的代码:Child c{ {}, 1 }
,并在升级到15.7后再回到继承时使用。