使用简单的ctor进行派生类的初始化 [英] Uniform initialization of derived class with trivial ctor

查看:200
本文介绍了使用简单的ctor进行派生类的初始化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图用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)这编译精细
Derived d {10,20,30}; // 2)这失败

标记为 2 的行失败, > clang 3.1 g ++ 4.7 的无匹配构造函数用于初始化派生

我不明白为什么,在Derived的情况下,它试图调用构造函数而不是执行(我不知道如何调用它,也许



下面的推理是错误的:



A)保证它可以静态初始化



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



我很困惑....

解决方案

无关紧要与你无关初始化一些东西。重要的是您的 Derived 类型是否为 aggregate ,而不是这样:



§8.5.1[dcl.init.aggr] p1


是一个数组或类(第9条),没有用户提供的构造函数(12.1),对于非静态数据成员没有 brace-or-equal-initializers (9.2),没有私有或受保护的非静态数据成员(第11条),没有基类(第10条),没有虚函数(10.3)。


只有聚合可以使用聚合初始化初始化,所以list-initialization(这是统一初始化的官方名称)只能尝试寻找一个拟合构造函数。



你可以做的是提供一个转换为基类的 constexpr 构造函数,并添加一个默认 ed默认构造函数:

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


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:

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.

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).

Something in the following reasoning is wrong?:

A) Being trivial guarantees it can be statically initialized

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?

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:

§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).

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 defaulted default constructor:

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

这篇关于使用简单的ctor进行派生类的初始化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆