Reputation: 22705
The following code compiles with Clang (3.9.1 tested) and GCC (6.3 tested), as shown in this link: https://godbolt.org/g/kO1nBa. However, MSVC (19.00.24215.1 tested) fails to compile it:
struct ValueWitnessTable {
int size;
};
struct ExtraInhabitantsValueWitnessTable : ValueWitnessTable {
constexpr ExtraInhabitantsValueWitnessTable(const ValueWitnessTable &base) : ValueWitnessTable(base) {}
};
struct ValueWitnessTableGenerator {
static constexpr const ExtraInhabitantsValueWitnessTable table = { { 1 } };
};
int main() {}
error C2131: expression did not evaluate to a constant
note: failure was caused by evaluation of an assignment operation
note: while evaluating 'ExtraInhabitantsValueWitnessTable::ExtraInhabitantsValueWitnessTable(ExtraInhabitantsValueWitnessTable{ValueWitnessTable{(null)}}, ValueWitnessTable{size=1})'
What's going on here - do the standards allow this? Is this a C++ 17 feature?
Also, how would I work around this? I need the behaviour of member-wise initializing the base class (because there is stuff that I've omitted involving macros etc.).
Upvotes: 1
Views: 81
Reputation: 22705
So I figured out the solution to this issue: use initializer lists instead:
struct ValueWitnessTable {
int size;
};
struct ExtraInhabitantsValueWitnessTable : ValueWitnessTable {
constexpr ExtraInhabitantsValueWitnessTable(const ValueWitnessTable &base) : ValueWitnessTable{base.size} {}
};
struct ValueWitnessTableGenerator {
static constexpr const ExtraInhabitantsValueWitnessTable table = { { 1 } };
};
int main() {}
For some reason initializer lists are supported as constexpr, but copy constructors that do the same thing are not.
Upvotes: 0