引用 base class 的 constexpr 构造函数因编译器而异

constexpr constructor referring to base class varies between compilers

以下代码使用 Clang(3.9.1 测试)和 GCC(6.3 测试)编译,如此 link:https://godbolt.org/g/kO1nBa 所示。然而,MSVC(19.00.24215.1 测试)编译失败:

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})'

这是怎么回事 - 标准是否允许这样做?这是 C++ 17 的特性吗?

此外,我该如何解决这个问题?我需要按成员初始化基础 class 的行为(因为我省略了涉及宏等的内容)。

所以我找到了这个问题的解决方案:改用初始化列表:

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() {}

由于某些原因,初始化列表作为 constexpr 被支持,但做同样事情的复制构造函数不被支持。