使用普通ctor统一初始化派生类

时间:2012-11-29 12:23:48

标签: c++ inheritance c++11 uniform-initialization list-initialization

我正试图用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.1g++ 4.7初始化Derived”消息。

我无法理解为什么,在Derived的情况下,它试图调用构造函数而不执行(我不知道如何调用它,可能聚合初始化?)第1行的情况。

以下推理中的某些内容是错误的?:

A)微不足道的保证可以静态初始化

B)要进行静态初始化,必须在运行时不执行代码,因此不需要构造函数调用 A+B =&gt;为什么它试图在一个它知道微不足道的类型上调用构造函数?

我很困惑....

1 个答案:

答案 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}{}
};