我不明白为什么这段代码可以编译通过而没有错误:
#include <iostream>
template <class T>
struct Test
{
static constexpr T f() {return T();}
};
int main()
{
Test<void> test;
test.f(); // Why not an error?
return 0;
}
这符合标准要求吗,还是编译器的容错机制?
constexpr函数的定义应满足以下约束条件:
并包括此项目符号:其返回类型必须是字面类型;
而在C++11中,void不是字面量,如第3.9节第10段所述,但是如果我们再看第6段,它给出了适合此情况的例外,它说:如果类模板的constexpr函数模板或成员函数的实例化模板专业化不符合constexpr函数或constexpr构造函数的要求,则该专业化不是constexpr函数或constexpr构造函数。[注:如果函数是成员函数,则仍将其作为下面所述的const。-结束说明] 如果没有模板的任何专业化会产生constexpr函数或constexpr构造函数,则程序无效;不需要诊断。
正如Casey在这里指出的那样,在C++14标准草案中,void是一个字面量,这是第3.9节类型的第10段所说的:如果它是:
并包括以下内容:void
不是 字面类型。然而,在C++14(N3797)中,void
被包括在 字面类型中。因此,OP的代码将符合C++14标准。 - Caseyconstexpr
但const
成员函数,或者在C++14中用于constexpr
和非const
成员函数! - Caseystatic
成员函数,那么你说的是正确的,但是OP有一个static
成员,所以无论如何它都不会是const
。请注意,白痴! - Caseyvoid()
的值,你并不是从一个void函数中返回。你返回了一个NULL
值。你所做的相当于这样:void f() { return void(); }
void foo() {} void bar() {return foo();}
。但我不确定。 - chrisvoid
(顺便说一下,在 C++ 中一直是合法的)吗?还是关于constexpr void
的组合? - AnT stands with Russia