回归虚空?

Vin*_*ent 26 c++ templates return void c++11

我不明白为什么这段代码编译没有错误:

#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;
}
Run Code Online (Sandbox Code Playgroud)

根据标准是否可以,还是编译器容差?

Sha*_*our 25

这看起来是有效的C++ 11标准草案,如果我们看一下5.2.3 显式类型转换(功能表示法)2段所说的(强调我的):

表达T() ,其中T是一个简单型说明符或类型名称说明符用于非阵列的完整的对象类型或(可能CV修饰)void类型,创建指定类型的prvalue,其值是通过值初始化(8.5)生成类型为T的对象; 没有为void()情况进行初始化.[...]

C++ 11之前的措辞非常相似.

即使段落段落说,这在constexpr中也没关系:7.1.53

constexpr函数的定义应满足以下约束:

并包括这个子弹:

其返回类型应为字面类型;

虚空不是字面C++ 11的每节3.910,如果我们再看看第6它给适合这种情况下的例外,它说:

如果constexpr函数模板的实例化模板特化或类模板的成员函数无法满足constexpr函数或constexpr构造函数的要求,则该特化不是constexpr函数或constexpr构造函数.[注意:如果函数是成员函数,它仍然是const,如下所述.-end note] 如果没有模板的特化会产生constexpr函数或constexpr构造函数,程序就会形成错误; 无需诊断.

正如Casey 在C++ 14中指出的那样,标准 void是一个文字,这是第10节的3.9 类型说:

类型是文字类型,如果它是:

包括:

- 无效; 要么


fil*_*mor 6

有关完整信息,请参阅@Shafik Yaghmour的答案.

以下段落禁止非模板(7.1.5(3)):

constexpr函数的定义应满足以下约束:

  • [...]

  • 它的返回类型应该是文字类型或对文字类型的引用

为了详细说明,文字类型在3.9(10)中定义为标量类型或数组或结构中文字类型对象的组合.void不是3.9(9)的标量类型.

  • @Casey我认为7.1.5第6段允许在C++ 11中使用它 (2认同)