简体   繁体   English

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

[英]Uniform initialization of derived class with trivial ctor

I'm trying to wrap my head around some corner cases with c++11 uniform initialization and I can't figure out why is this: 我试图用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

Line marked 2 fails with a "no matching constructor for initialization of Derived" message both with clang 3.1 and g++ 4.7 . 使用clang 3.1g++ 4.7标记为2的行失败,并且“没有用于初始化Derived的匹配构造函数”消息。

I can't understand why, in case of Derived, it is trying to call a constructor and not performing (I don't know how to call it, maybe aggregate initialization ?) as is the case for line 1). 我无法理解为什么,在Derived的情况下,它试图调用构造函数而不执行(我不知道如何调用它,可能是聚合初始化 ?),就像第1行的情况一样。

Something in the following reasoning is wrong?: 以下推理中的某些内容是错误的?:

A) Being trivial guarantees it can be statically initialized A)微不足道的保证它可以静态初始化

B) To be statically initialized no code must be executed at runtime and hence no constructor call is required A+B => why is it trying to call a constructor on a type that it knows being trivial? B)要静态初始化没有代码必须在运行时执行,因此不需要构造函数调用A+B =>为什么它试图在一个它知道微不足道的类型上调用构造函数?

I'm very confused.... 我很困惑....

Being trivial has nothing to do with how you can initialize something. 微不足道与如何初始化某事无关。 The important bit is whether your Derived type is an aggregate , which is not the case: 重要的一点是您的Derived类型是否是聚合 ,而不是这种情况:

§8.5.1 [dcl.init.aggr] p1

An aggregate is an array or a class (Clause 9) with no user-provided constructors (12.1), no brace-or-equal-initializers for non-static data members (9.2), no private or protected non-static data members (Clause 11), no base classes (Clause 10) , and no virtual functions (10.3). 聚合是一个数组或类(第9节),没有用户提供的构造函数(12.1),非静态数据成员(9.2)没有大括号或等于初始值,没有私有或受保护的非静态数据成员(第11条), 没有基类(第10条) ,没有虚函数(10.3)。

Only aggregates can be initialized with aggregate initialization, so list-initialization (which is the official name for uniform initialization) can only try looking for a fitting constructor. 只有聚合可以使用聚合初始化进行初始化,因此列表初始化(这是统一初始化的官方名称)只能尝试查找拟合构造函数。

What you can do is provide a constexpr constructor that forwards to the base-class, and add a default ed default constructor: 你可以做的是提供一个constexpr构造函数,它转发到基类,并添加一个default ed默认构造函数:

struct Derived : Base{
    Derived() = default;
    constexpr Derived(int a, int b, int c) : Base{a, b, c}{}
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM