具有模板化基类型的派生结构的结构初始化



我试图在模板结构体派生上使用结构体初始化。代码是这样的:

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<MoveEvent>更改为Event<int>会产生相同的问题。此外,我认为这是POD的问题,但std::is_podMoveEvent返回true。那么问题是什么呢?为什么我不能使用结构体初始化?

只能在聚合上进行聚合初始化。聚合是,from [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
}

不能使用这种语法有两个原因,首先,"指定初始化式"是C的特性,而不是c++的特性

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

其次,不能对派生类使用聚合初始化,因为一旦引入继承,就不再拥有POD聚合类型。

最好是为派生类

定义一个构造函数。
struct MoveEvent: Event<MoveEvent>
{
    MoveEvent(int _x, int _y) : x{_x}, y{_y} {}
    int x, y;
};

那么你可以这样做

MoveEvent event{5, 4};

最新更新