返回void? [重复]

问题描述 投票:0回答:3

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

#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;
}

按照标准可以吗,还是编译器可以容忍?

c++ templates c++11 return void
3个回答
25
投票

根据C++11标准草案,这看起来是有效的,如果我们看一下第

5.2.3
显式类型转换(函数符号)段落2说(强调我的):

表达式 T(),其中 T 是简单类型说明符或 非数组完整对象类型的类型名说明符 或 (可能是 cv 限定的)void 类型,创建 指定类型,其值是通过值初始化产生的 (8.5) T 类型的对象; void() 没有进行初始化 案例。[...]

措辞也非常相似 C++11 之前

这在 constexpr 中没问题,尽管第

7.1.5
段落
3
说:

constexpr函数的定义应满足以下条件 限制条件:

并包括此项目符号:

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

and void 不是 C++11 中的 literal,根据第

3.9
段落 10但是,如果我们然后查看第 6 段落,它给出了适合这种情况的例外,它说:

如果 constexpr 函数的实例化模板特化 类模板的模板或成员函数将无法满足 constexpr 函数或 constexpr 构造函数的要求, 该专门化不是 constexpr 函数或 constexpr 构造函数。 [ 注意:如果该函数是成员函数,它将 仍然是 const ,如下所述。 —尾注] 如果没有专业化 模板将生成 constexpr 函数或 constexpr 构造函数,程序格式错误;无需诊断

正如 Casey C++14 草案标准中指出的那样void是一个文字,这是第

3.9
类型段落10说:

如果满足以下条件,则类型是文字类型:

并包括:

——无效;或


6
投票

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

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

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

  • [...]

  • 其返回类型应为文字类型或对文字类型的引用

详细来说,3.9(10)中将文字类型定义为标量类型或数组或结构中文字类型对象的组合。根据 3.9(9),

void
不是标量类型。


1
投票

您的函数返回

void()
的值,您本身并不是从 void 函数返回。您正在返回一个
NULL
值。你正在做的事情相当于这样:

void f() { return void(); }

这会返回一个空值,唯一的空值。您不能从 void 函数返回任何其他内容,因为它将是不同的类型。

© www.soinside.com 2019 - 2024. All rights reserved.