"void()"有什么用?

How is "void()" useful?

本文关键字:什么 void      更新时间:2023-10-16

不能声明void变量:

void fn() {
void a; // ill-formed
}

然而,这编译:

void fn() {
void(); // a void object?
}

void()是什么意思?它有什么用?为什么void a;格式不正确,而void()没问题?

void fn() {
void a = void(); // ill-formed
}

语句

void();

创建一个 void 值,然后将其丢弃。 (除了丢弃或返回它之外,您实际上不能对 void 值执行太多操作。

该标准†在 5.2.3 [expr.type.conv 中说

表达式 T(),其中 T 是非数组完整对象的简单类型说明符或类型名说明符 类型或(可能符合 CV 条件的)void 类型,创建指定类型的 PR值,其值为 通过值初始化 (8.5) 生成类型 T 的对象;没有对 void() 情况进行初始化

请注意,它明确指出void()是合法的。

† 我的链接是 N4296,这是 C++14 之前的最后一份公共委员会草案,但是该标准的各种版本在这里没有变化。


编辑

有用吗? 明确地像这样?不。 我看不出它的用途。 但是,它在模板函数中很有用,这些函数有时会执行以下操作:

template <typename T>
T foo() {
if (prepare_for_for()) {
return do_foo();
} else {
return T();
}
}

即使对于T==void,这也将起作用.

语法上void()是用函数表示法编写的显式类型转换(参见 5.2.3)。

请注意,即使在"经典"C (C89/90) 中,也已经允许显式转换为void。当然,在 C 语言中,必须使用"经典"C 样式的强制转换符号并提供参数。任何表达式都可以转换为 C 中的void,包括已void的表达式。此功能原封不动地迁移到 C++ 中显式类型转换的强制表示法(它由其功能的static_cast分支处理,即您可以在 C++ 中static_castvoid)。

考虑到上述因素,转换为void也始终得到替代C++强制转换语法 -函数表示法的支持也就不足为奇了。一旦您了解了这一点,它被扩展为支持"无参数"版本 -void()也就不足为奇了。

这在C++中的有用性将包括诸如泛型函数之类的上下文

template <typename T>
T foo() {
...;
return T(); // remains valid even when `T == void`
}

请注意,在C++中,从void函数返回void伪值是完全合法的。创建此类伪值的能力void()消除了为上述函数编写专用void专用化的需要。


作为旁注,仅当上下文强制显式类型转换被解释为表达式时,void()才代表显式类型转换,如示例中所示。当上下文调用类型名称时(例如int foo(void())using T = void();)它实际上声明了一个返回void并且不接受任何参数的无名函数。