【发布时间】:2020-10-27 15:54:59
【问题描述】:
我使用的标准是c++17。
问题是我想重新制作我的代码并使用 CRPT 重新组织我的代码结构,因为它非常适合,但问题是以前的代码在类中使用聚合初始化,例如:
ClassWithNoParent get(const T_& unit) const {
return {.w = 1,
.h = 1,
.c = 1,
.n = 1};
}
没关系。当我使用 CRTP 时
class DefaultClass {
public:
int n;
int c;
int h;
int w;
};
template <class SuccessorT, class T = DefaultClass>
class BaseCRTPClass {
public:
int w;
int h;
int c;
int n;
SuccessorT get(const DefaultClass&) const {
return {.w = 1,
.h = 1,
.c = 1,
.n = 1};
}
};
class Successor : public BaseCRTPClass<Successor> {};
int main(){
Successor t;
auto k = t.get(DefaultClass{});
}
编译失败并报错
21:25: error: could not convert '{1, 1, 1, 1}' from '<brace-enclosed initializer list>' to 'Successor'
这是预期的,因为标准希望 Successor 被聚合,但是我不太确定 c++17 严格禁止没有基类。它限制了构造函数(据我了解,但我可能错了)。那么,我怎样才能绕过这个问题呢?
如何为 CRTP 定义的派生类保留聚合初始化?
附:为什么要保留聚合初始化?因为我的代码中很多地方都使用了这种初始化,但是如果在 CRTP 中重新制作,那么一切都会被粉碎,我将不得不替换某些构造函数上的所有聚合初始化......
【问题讨论】:
-
Successor 已经是一个聚合。这不是问题的来源。我不确定该怎么做,但请查看this。显然指定
SuccessorT并删除第一个参数的指定名称会使代码编译。