看看这段代码:
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 aconstexpr
function template or member function of a class template would fail to satisfy the requirements for aconstexpr
function orconstexpr
constructor, that specialization is still aconstexpr
function orconstexpr
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 aconstexpr
function orconstexpr
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/