如何在带有 CRTP 模式的派生 class 中使用聚合初始化?
How to use aggregated initialization in derived class with CRTP pattern?
我使用的标准是c++17
。
问题是我想重新制作我的代码并用 CRPT 重新组织我的代码结构,因为它非常适合,但问题是以前的代码在 classes 中使用聚合初始化,例如:
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
是否严格禁止没有基础class。它限制了构造函数(据我所知,但我可能是错的)。那么,我怎样才能绕过这个问题呢?
如何为 CRTP 定义的派生 class 保留聚合初始化?
P.S。为什么要保留聚合初始化?因为我的代码中很多地方都使用了这个初始化,但是如果在 CRTP 中重新制作,那么一切都会被粉碎,我将不得不替换一些构造函数上的所有聚合初始化...
问题与 CRTP 无关。派生 classes 的聚合初始化仅在 C++17 中引入。要 aggregate-initialize 派生 class,必须将基 class 初始化为它自己的初始化列表中的第一项。因此,要使其正常工作,请使用 double-brace:
return {{.w = 1, .h = 1, .c = 1, .n = 1}};
为了说明,假设你有一个更简单的,non-template class:
struct Base { int a; };
struct Derived : public Base { int b; };
您必须将 Base
初始化为第一项:
Derived x = {
{ .a = 42 }, // Base
.b = 24 // b
};
我使用的标准是c++17
。
问题是我想重新制作我的代码并用 CRPT 重新组织我的代码结构,因为它非常适合,但问题是以前的代码在 classes 中使用聚合初始化,例如:
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
是否严格禁止没有基础class。它限制了构造函数(据我所知,但我可能是错的)。那么,我怎样才能绕过这个问题呢?
如何为 CRTP 定义的派生 class 保留聚合初始化?
P.S。为什么要保留聚合初始化?因为我的代码中很多地方都使用了这个初始化,但是如果在 CRTP 中重新制作,那么一切都会被粉碎,我将不得不替换一些构造函数上的所有聚合初始化...
问题与 CRTP 无关。派生 classes 的聚合初始化仅在 C++17 中引入。要 aggregate-initialize 派生 class,必须将基 class 初始化为它自己的初始化列表中的第一项。因此,要使其正常工作,请使用 double-brace:
return {{.w = 1, .h = 1, .c = 1, .n = 1}};
为了说明,假设你有一个更简单的,non-template class:
struct Base { int a; };
struct Derived : public Base { int b; };
您必须将 Base
初始化为第一项:
Derived x = {
{ .a = 42 }, // Base
.b = 24 // b
};