Reputation: 249
The standard that I use is c++17
.
The problem is that I want to remake my code and reorganize the structure of my code with CRPT because it fits very well but the problem is that previous code uses aggregated initialization within classes like:
ClassWithNoParent get(const T_& unit) const {
return {.w = 1,
.h = 1,
.c = 1,
.n = 1};
}
and it's fine. When I use 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{});
}
The compilation fails with the error
21:25: error: could not convert '{1, 1, 1, 1}' from '<brace-enclosed initializer list>' to 'Successor'
It's expected because standard wants Successor
to be aggregated, however I am not quite sure that c++17
strictly forbids to have no base class. It restricts constructor (as I understood, but I may be wrong). So, how could I get this problem bypass?
How can I keep aggregated initialization for the derived class that is defined by CRTP?
P.S. Why do I want to keep the aggregated initialization? Because many places in my code uses this initialization, but if will remake in CRTP, then everything will be crushed and I will be obliged to replace all aggregated initializations on some constructors...
Upvotes: 1
Views: 223
Reputation: 4079
The problem is unrelated to CRTP. Aggregate initialization of derived classes was only introduced in C++17. To aggregate-initialize a derived class, the base class must be initialized as the first item, in its own initializer list. So to get this working, use a double-brace:
return {{.w = 1, .h = 1, .c = 1, .n = 1}};
To illustrate, say you have a simpler, non-template class:
struct Base { int a; };
struct Derived : public Base { int b; };
You have to initialize Base
as the first item:
Derived x = {
{ .a = 42 }, // Base
.b = 24 // b
};
Upvotes: 2