我正试图用c ++ 11统一初始化来解决一些极端情况,我无法弄清楚为什么会这样:
struct Base
{
int x,y,z;
};
struct Derived : Base
{
};
static_assert (std::is_trivial<Base>::value, "Base must be trivial");
static_assert (std::is_trivial<Derived>::value, "Derived must be trivial");
Base b{1, 2, 3}; // 1) This compiles fine
Derived d{10, 20, 30}; // 2) This fails
标记为 2 的行标记为“无匹配构造函数,无法使用clang 3.1
和g++ 4.7
初始化Derived”消息。
我无法理解为什么,在Derived的情况下,它试图调用构造函数而不执行(我不知道如何调用它,可能聚合初始化?)第1行的情况。
以下推理中的某些内容是错误的?:
A)微不足道的保证可以静态初始化
B)要进行静态初始化,必须在运行时不执行代码,因此不需要构造函数调用
A+B
=&gt;为什么它试图在一个它知道微不足道的类型上调用构造函数?
我很困惑....
答案 0 :(得分:11)
琐碎与如何初始化某事无关。重要的一点是您的Derived
类型是聚合,情况并非如此:
§8.5.1 [dcl.init.aggr] p1
聚合是一个数组或类(第9条),没有用户提供的构造函数(12.1),没有大括号或等于初始化静态数据成员(9.2),没有私有或受保护的非静态数据成员(第11条),没有基类(第10条),没有虚函数(10.3)。
只能使用聚合初始化来初始化聚合,因此列表初始化(这是统一初始化的官方名称)只能尝试寻找合适的构造函数。
您可以做的是提供转发到基类的constexpr
构造函数,并添加default
ed默认构造函数:
struct Derived : Base{
Derived() = default;
constexpr Derived(int a, int b, int c) : Base{a, b, c}{}
};