我试图在模板结构体派生上使用结构体初始化。代码是这样的:
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_pod
为MoveEvent
返回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};