【问题标题】:Struct initialization of derived struct with a templated base type [duplicate]具有模板化基类型的派生结构的结构初始化[重复]
【发布时间】:2015-08-03 18:11:29
【问题描述】:

我正在尝试对从模板结构派生的结构初始化。代码是这样的:

template <class Derived>
struct Event{
//the level of access on the ctor has nothing to do with the problem
//protected:
//    Event() = default;
};

struct MoveEvent: Event<MoveEvent>{
    int x, y;
};


int main(){
    //how do I make this work?
  //MoveEvent event = {.x =5, .y = 4};
}

我认为这可能与 CTRP 有关,但将 Event&lt;MoveEvent&gt; 更改为 Event&lt;int&gt; 会产生同样的问题。此外,我认为这是 POD 的问题,但 std::is_podMoveEvent 返回 true。那么这里有什么问题呢?为什么我不能使用结构初始化?

【问题讨论】:

  • C++ 不支持 C99 指定的初始值设定项。
  • 但我使用的是 C++11。
  • @user975989 没关系,那是C特性,不是C++特性
  • 您尝试MoveEvent event = {.5, 4}; 了吗?也请把你收到的逐字错误信息放在你的问题中。
  • 啊。所以问题在于继承,因为非继承 MoveEvent 有效。

标签: c++ c++11


【解决方案1】:

您只能对聚合进行聚合初始化。聚合来自 [dcl.init.aggr]:

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

MoveEvent 不是聚合。因此,您将不得不添加一个构造函数:

template <class Derived>
struct Event {
};

struct MoveEvent: Event<MoveEvent> {
    MoveEvent(int x, int y) : x(x), y(y) { }
    int x, y;
};


int main() {
    MoveEvent event{5, 4}; // NOW this is fine
}

【讨论】:

    【解决方案2】:

    你不能使用这个语法有几个原因,首先“指定初始化器”是一个 C 特性,not a C++ feature

    MoveEvent event = {.x = 5, .y = 4};
    

    其次,你不能对派生类使用聚合初始化,因为一旦你引入继承,你no longer have a POD aggregate type

    最好的办法是为派生类定义一个构造函数

    struct MoveEvent: Event<MoveEvent>
    {
        MoveEvent(int _x, int _y) : x{_x}, y{_y} {}
        int x, y;
    };
    

    那么你可以这样做

    MoveEvent event{5, 4};
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-21
      • 2019-03-12
      • 2021-04-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多