【问题标题】:constexpr constructor referring to base class varies between compilers引用基类的 constexpr 构造函数因编译器而异
【发布时间】:2017-02-11 10:00:28
【问题描述】:

以下代码使用 Clang(3.9.1 测试)和 GCC(6.3 测试)编译,如以下链接所示: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() {}

错误 C2131:表达式未计算为常量

注意:失败是由赋值操作的评估引起的

注意:在评估“ExtraInhabitantsValueWitnessTable::ExtraInhabitantsValueWitnessTable(ExtraInhabitantsValueWitnessTable{ValueWitnessTable{(null)}}, ValueWitnessTable{size=1})”时

这里发生了什么 - 标准允许这样做吗?这是 C++ 17 的功能吗?

另外,我将如何解决这个问题?我需要以成员方式初始化基类的行为(因为有些东西我已经省略了涉及宏等)。

【问题讨论】:

  • 引用自 cppreference:每个被选择用于初始化非静态成员和基类的构造函数都必须是 constexpr 构造函数。从 c++14 开始
  • @felix 很高兴知道 - 如果您愿意,请随时回答!你知道我该如何解决这个 MSVC 的限制

标签: c++ visual-c++ clang language-lawyer standards


【解决方案1】:

所以我想出了解决这个问题的办法:改用初始化列表:

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,但做同样事情的复制构造函数不支持。

【讨论】:

    猜你喜欢
    • 2018-10-04
    • 1970-01-01
    • 2023-01-05
    • 1970-01-01
    • 2017-10-31
    • 2017-08-11
    • 1970-01-01
    • 1970-01-01
    • 2021-03-18
    相关资源
    最近更新 更多