当前位置: 首页 > 知识库问答 >
问题:

启用默认初始值设定项列表构造函数

越麒
2023-03-14

我相信现代C初始值设定项列表对于初始化对象非常有用,甚至不需要定义自己的构造函数:

struct point
{
    float coord[3];
};

point p = {1.f, 2.f, 3.f}; // nice !

但是,当我的类从另一个类继承时,这不起作用:

template<typename T>
class serializable
{
    protected:
        serializable() = default;
    ...
    // other stuff
}

struct point : public serializable<point>
{
    float coord[3];
};
point p = {1.f, 2.f, 3.f}; // Doesn't work :(

我尝试添加point()=默认值 到我的点类,但这也不起作用。我怎么还能用初始值设定项列表初始化点?


共有1个答案

商迪
2023-03-14

您的原始案例依赖于聚合初始化[dcl.init.list]:

类型T的对象或引用的列表初始化定义如下:-否则,如果T是聚合,则执行聚合初始化

其中,从[dcl.init.aggr]中,聚合和聚合初始化是:

聚合是一个数组或类(第9条),没有用户提供的构造函数(12.1),没有私有或受保护的非静态数据成员(第11条),没有基类(第10条),没有虚拟函数(10.3)。

当聚合由初始化器列表初始化时,如8.5.4所述,初始化器列表的元素被视为聚合成员的初始化器,按下标或成员顺序递增。每个成员都从相应的初始化子句复制初始化。

但是现在,由于点有一个基类(serializable

解决方案是简单地提供这样一个构造函数来初始化point

struct point : public serializable<point>
{
    template <typename... T>
    point(T... ts) 
    : coord{ts...}
    { } 

    float coord[3];
};

 类似资料:
  • 由于某些原因,即使使用成员初始值设定项,我也会遇到无默认构造函数错误。我做错了什么? 一个最小的例子, a、 cpp a、 h b.cpp b、 h

  • 所以我正在学习构造函数初始值设定项列表,我写了以下代码: 为此我使用了g编译器。它调用的是构造函数而不是复制构造函数。它应该调用复制构造函数,因为我正在创建一个对象来创建另一个对象?这里的问题是什么,标准对此怎么说?

  • 我有以下代码: 我希望输出是:“base constructor,test:50”,但事实并非如此,因为构造函数是在初始化之前调用的,没有错误或警告,它只是编译。 有什么方法可以让构造函数在之后被调用吗?或者这是总体上的糟糕设计? 我正在尝试将所有的init方法和它们的调用放入构造函数insted中,这个行为阻止了我这样做。

  • 问题内容: 我有一个对象 我用两种方式初始化它 这是输出 似乎builder没有获得默认值。我在属性中添加了注释,对象现在看起来像这样 这是控制台输出 我怎样才能使他们俩都成为? 问题答案: 我的猜测是,这是不可能的(没有删除代码)。但是,为什么不仅仅实现所需的构造函数呢?Lombok旨在使您的生活更轻松,如果Lombok无法解决某些问题,请按照老式的方式进行操作。 控制台输出:

  • 主要内容:初始化 const 成员变量构造函数的一项重要功能是对成员变量进行初始化,为了达到这个目的,可以在构造函数的函数体中对成员变量一一赋值,还可以采用 初始化列表。 C++构造函数的初始化列表使得代码更加简洁,请看下面的例子: 运行结果: 小明的年龄是15,成绩是92.5 李华的年龄是16,成绩是96 如本例所示,定义构造函数时并没有在函数体中对成员变量一一赋值,其函数体为空(当然也可以有其他语句),而是在函数首部与函数体之间添

  • 我有一个这样的类,除了有多个成员: 我基本上希望对其进行聚合初始化,如下所示: 但由于自定义构造函数的原因,这似乎是不可能的,因此我想使用构造函数参数来模拟它: 这看起来有很多冗余,只是为了在可能的情况下移动和复制,尤其是在成员数量激增的情况下。我想我想要完美的转发? 但是现在我不能像这样使用空的初始化列表调用它: 因为无法推导出初始化列表参数类型。有没有不需要我写的解决方案 ?