这是一个错误吗? Constexpr构造函数无声地变为非constexpr [英] Is this a bug? Constexpr constructor silently becomes non-constexpr
问题描述
看下面的代码:
struct NonConstexpr {
NonConstexpr() { }
};
template <typename T>
struct Bar {
NonConstexpr nonConstexpr;
constexpr Bar() { }
};
struct Foo {
Bar<void> bar;
constexpr Foo() { }
};
Foo
具有成员Foo::bar::nonConstexpr
,该成员具有非constexpr构造函数.因此,我期望它不应该编译.但是它可以使用gcc,clang和msvc进行编译.这是编译器错误,还是某些规则允许该代码进行编译?
Foo
has a member, Foo::bar::nonConstexpr
, which has a non-constexpr constructor. So, my expectation is that this should not compile. But it compiles with gcc, clang and msvc. Is this a compiler bug, or some rule allows this code to compile?
如果我直接将NonConstexpr
成员添加到Foo
中,则代码将不再编译.
If I add a NonConstexpr
member into Foo
directly, the code doesn't compile anymore.
(我遇到了这个问题,因为我期望对全局Foo
对象进行静态初始化,但是由于静态初始化顺序失败",所以它进行了动态初始化,并引起了问题)
(I got this problem, because I've expected static initialization for a global Foo
object, but it got dynamically initialized, and it caused a problem, because of "static initialization order fiasco")
推荐答案
这是编译器错误,还是某些规则允许此代码进行编译?
Is this a compiler bug, or some rule allows this code to compile?
允许编译的规则是:
10.1.5 constexpr规范[dcl.constexpr]
...
6.如果constexpr
函数模板或类模板的成员函数的实例化模板专业化不能满足constexpr
函数或constexpr
构造函数的要求,则该专业化仍然是constexpr
函数或constexpr
构造函数,即使对此类函数的调用不能出现在常量表达式中.如果当模板被认为是非模板函数或构造函数时,如果模板的专业化不能满足constexpr
函数或constexpr
构造函数的要求,则模板格式错误,无需诊断.
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.
The above quote is taken from CPP standard draft N4713.
从引号中可能还不清楚,因为Foo
的构造函数是constexpr
,Bar<void>
的构造函数如何出现在Foo
的构造函数中.但是如注释中所述,constexpr
与常量表达式不同. Foo
的构造函数不是表达式,更不用说常量表达式.
From the quote it may not be clear how Bar<void>
's constructor can appear in Foo
's constructor as Foo
's constructor is constexpr
. But as noted in the comments, constexpr
is not the same as constant expression. Foo
's constructor is is not an expression, much less a constant expression.
这篇关于这是一个错误吗? Constexpr构造函数无声地变为非constexpr的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!