带有委托构造函数的 constexpr

Posted

技术标签:

【中文标题】带有委托构造函数的 constexpr【英文标题】:constexpr with delegating constructors 【发布时间】:2015-09-09 21:49:03 【问题描述】:

我必须遵循以下代码:

class IP4Address

    public:
    constexpr IP4Address();
    constexpr IP4Address(uint32_t a_IP, uint16_t a_Port);

    private:
    uint32_t m_IP;
    uint16_t m_Port;
;

constexpr IP4Address::IP4Address():
    IP4Address(0, 0)




constexpr IP4Address::IP4Address(uint32_t a_IP, uint16_t a_Port):
    m_IP(a_IP),
    m_Port(a_Port)



这会导致以下错误 (Visual Studio 2015):

error C2476: 'constexpr' constructor does not initialize all members
note: 'IP4Address::m_IP' was not initialized by the constructor
note: 'IP4Address::m_Port' was not initialized by the constructor

这是无效的 C++ 吗?难道我做错了什么?或者这可能是编译器错误?

【问题讨论】:

在将uint32 更改为uint32_t 并将uint16 更改为uint16_t 后,使用g++ 4.9.3 对我来说效果很好。 也许它与 blogs.msdn.com/b/vcblog/archive/2015/06/02/… 有关,引用:“我不知道 STL 中有任何 constexpr 错误,但仍有一些编译器错误需要修复 - 特别是 DevDiv#1134662 “constexpr 构造函数正在发出动态初始化程序”和 1165072“带有括号省略的 constexpr ICE”在我们的内部数据库中。“ 在将uint32 更改为uint32_t 并将uint16 更改为uint16_t 后,我可以在MSVC 2015 中重现,但不能在g++ 上重现(coliru.stacked-crooked.com/a/0c22a7bd8d64ccc3) 【参考方案1】:

这是 MSVC 2015 中的一个错误。C++ 11 文档§7.1.5 4 非常清楚地说:

4. constexpr 构造函数的定义应满足以下约束

4.1该类不应有任何虚拟基类

4.2每个参数类型都应该是文字类型

4.3 它的函数体不能是函数尝试块;

另外,它的函数体要么是=delete,要么满足以下约束:

4.4 其函数体应为 = default,或者其函数体的复合语句应满足 constexpr 函数的函数体的约束;

4.5每个非变体非静态数据成员和基类子对象都应该被初始化

4.6 如果类是具有变体成员的联合 (9.5),则应初始化其中的一个;

4.7 如果该类是类联合类,但不是联合,则对于其每个具有变体成员的匿名联合成员,应初始化其中一个;

4.8 对于非委托构造函数,每个被选择用来初始化非静态数据成员和基类子对象的构造函数都应该是 一个 constexpr 构造函数;

4.9 对于委托构造函数,目标构造函数应为 constexpr 构造函数。

您的班级符合所有标准。 Clang 和 GCC 也接受您的消息来源,所以如果我忽略了某些内容,我会感到惊讶。

【讨论】:

以上是关于带有委托构造函数的 constexpr的主要内容,如果未能解决你的问题,请参考以下文章

为啥编译器无法确定构造函数实际上是 constexpr?

委托构造函数详解,小白也可以看懂

[C++11 类的改进] --- 继承构造函数和委托构造函数

[C++11]委托构造函数

C++11 继承构造函数和委托构造函数

C++11 继承构造函数和委托构造函数