以下代码无法编译:
// template<class>
struct S {
int g() const {
return 0;
}
constexpr int f() const {
return g();
}
};
int main()
{
S /*<int>*/ s;
auto z = s.f();
}
例如,GCC 会提示:错误:调用非 constexpr 函数‘int S::g() const’。这是完全合理的。但是如果我把 S 变成一个模板,代码就会编译(用 MSVC 15.3、GCC 7.1.0、clang 4.0.1 检查)。
为什么? constexpr 在类模板中有什么特殊含义吗?
据我了解,这段代码是不正确的,但标准并不要求编译器产生错误(为什么?)。
最佳答案
根据 [dcl.constexpr]
The definition of a constexpr function shall satisfy the following constraints:
...
every constructor call and implicit conversion used in initializing the return value (6.6.3, 8.5) shall be one of those allowed in a constant expression
调用
g()
不允许出现在常量表达式中。根据 [expr.const]:A conditional-expression is a core constant expression unless it involves one of the following as a potentially evaluated subexpression...:
— an invocation of a function other than [...] aconstexpr
function
看起来有些编译器可能允许你做你正在做的事情,因为
z
未声明 constexpr
所以在编译时不需要知道这个值。如果您将代码更改为constexpr auto z = s.f();
您会注意到,所有这些编译器都将进行 barf、模板与否。
关于c++ - 类模板中的 Constexpr 成员函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46119548/