c++ - 这是一个错误吗? constexpr 构造函数静默变为非 constexpr

标签 c++ language-lawyer c++17

看看这段代码:

struct NonConstexpr {
    NonConstexpr() { }
};

template <typename T>
struct Bar {
    NonConstexpr nonConstexpr;

    constexpr Bar() { }
};

struct Foo {
    Bar<void> bar;

    constexpr Foo() { }
};

Foo 有一个成员 Foo::bar::nonConsexpr,它有一个非 constexpr 构造函数。所以,我的期望是这不应该编译。但它使用 gcc、clang 和 msvc 编译。这是编译器错误,还是某些规则允许此代码编译?

如果我将 NonConsexpr 成员直接添加到 Foo 中,代码将不再编译。

(我遇到了这个问题,因为我预计全局 Foo 对象的静态初始化,但它被动态初始化,并且由于“静态初始化顺序失败”而导致问题)

最佳答案

Is this a compiler bug, or some rule allows this code to compile?

允许编译的规则是:

10.1.5 The constexpr specifier [dcl.constexpr]
...
6. If the instantiated template specialization of a constexpr function template or member function of a class template would fail to satisfy the requirements for a constexpr function or constexpr constructor, that specialization is still a constexpr function or constexpr constructor, even though a call to such a function cannot appear in a constant expression. If no specialization of the template would satisfy the requirements for a constexpr function or constexpr constructor when considered as a non-template function or constructor, the template is ill-formed, no diagnostic required.

以上引用摘自 CPP 标准草案 N4713。


从报价中可能不清楚Bar<void>的构造函数可以出现在Foo的构造函数为 Foo的构造函数是 constexpr .但正如评论中所述,constexpr与常量表达式不同。 Foo的构造函数不是表达式,更不是常量表达式。

关于c++ - 这是一个错误吗? constexpr 构造函数静默变为非 constexpr,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53630837/

相关文章:

c++ - constexpr 函数可以包含标签吗?

c++ - 在 C++ 中创建节点的不同方式感到困惑?

c++ - 是否可以检查是否为给定类型和参数定义了用户文字?

c++ - 使用 MySQL C API 和 C++ 获取 MySQL 数据库表中的行

c++ - 如何制作一个哈希键来匹配/比较类似文本/html 的哈希?

c++ - 以逗号分隔的表达式调用析构函数

c++ - 在类中声明类型别名的替代方法

c++ - std::unique 可以用来确定自定义类的对象是否具有相同的值吗?

c++ - 代码 : expected ' ; ' before ' { ' token -- what is causing this? 中的解析错误

c++:数组中的类成员有多远(以字节为单位)?