8

我试图用 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的行失败,并带有 和 的“没有匹配的 Derived 初始化构造函数”消息。clang 3.1g++ 4.7

我不明白为什么在 Derived 的情况下,它试图调用构造函数而不执行(我不知道如何调用它,也许是聚合初始化?)就像第 1 行的情况一样)。

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

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

B)要静态初始化,不需要在运行时执行任何代码,因此不需要构造函数调用 A+B=>为什么它试图调用它知道微不足道的类型的构造函数?

我很困惑......

4

1 回答 1

11

琐碎与如何初始化某些东西无关。重要的是您的Derived类型是否为aggregate,事实并非如此:

§8.5.1 [dcl.init.aggr] p1

聚合是一个数组或一个类(第 9 条),没有用户提供的构造函数(12.1),没有用于非静态数据成员的大括号或等号初始化器(9.2),没有私有或受保护的非静态数据成员(第 11 条),没有基类(第 10 条),也没有虚函数(10.3)。

聚合初始化只能初始化聚合,所以list-initialization(统一初始化的官方名称)只能尝试寻找合适的构造函数。

您可以做的是提供一个constexpr转发到基类的构造函数,并添加一个defaulted 默认构造函数:

struct Derived : Base{
    Derived() = default;
    constexpr Derived(int a, int b, int c) : Base{a, b, c}{}
};
于 2012-11-29T12:41:37.400 回答