"void()" 有什么用?
How is "void()" useful?
您不能声明 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();
创建一个空值然后丢弃它。 (除了丢弃它或 return 之外,您实际上不能对 void 值做太多事情。)
5.2.3中的standard†[expr.type.conv
The expression T(), where T is a simple-type-specifier or typename-specifier for a non-array complete object
type or the (possibly cv-qualified) void type, creates a prvalue of the specified type, whose value is that
produced by value-initializing (8.5) an object of type T; no initialization is done for the void() case
请注意,它明确指出 void()
是合法的。
† 我的 link 是 N4296,它是 C++14 之前的最后一个 public 委员会草案,但是标准的各种版本在这里没有变化。
编辑
有用吗?明明这样?不,我看不出它有什么用。它 是 然而,在模板函数中很有用,有时会做类似的事情:
template <typename T>
T foo() {
if (prepare_for_for()) {
return do_foo();
} else {
return T();
}
}
这会起作用,即使是 T
== void
。
语法上void()
是用函数符号(见5.2.3)编写的显式类型转换。
请注意,即使在 "classic" C (C89/90) 中,也已经允许显式转换为 void
。当然,在 C 中,必须使用 "classic" C 风格的强制转换符号并提供一个参数。在 C 中,任何表达式都可以转换为 void
,包括已经是 void
的表达式。此功能未更改地迁移到 C++ 中显式类型转换的 cast notation(它由其功能的 static_cast
分支处理,即您可以 static_cast
到 void
在 C++ 中)。
考虑到上述情况,转换为 void
也得到替代 C++ 强制转换语法 - 函数符号 的一致支持也就不足为奇了。一旦你理解了这一点,它被扩展以支持 "argument-less" 版本就不足为奇了 - void()
.
this 在 C++ 中的用途将包括泛型函数等上下文
template <typename T>
T foo() {
...;
return T(); // remains valid even when `T == void`
}
请注意,在 C++ 中,void
函数的 return void
伪值是完全合法的。创建此类 void()
伪值的能力消除了为上述函数编写专用 void
特化的需要。
作为旁注,void()
仅在上下文强制将其解释为 表达式 时才代表显式类型转换,如您的示例所示。当上下文调用类型名称(例如 int foo(void())
或 using T = void();
)时,它实际上声明了一个 returns void
且不带参数的无名函数。
您不能声明 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();
创建一个空值然后丢弃它。 (除了丢弃它或 return 之外,您实际上不能对 void 值做太多事情。)
5.2.3中的standard†[expr.type.conv
The expression T(), where T is a simple-type-specifier or typename-specifier for a non-array complete object type or the (possibly cv-qualified) void type, creates a prvalue of the specified type, whose value is that produced by value-initializing (8.5) an object of type T; no initialization is done for the void() case
请注意,它明确指出 void()
是合法的。
† 我的 link 是 N4296,它是 C++14 之前的最后一个 public 委员会草案,但是标准的各种版本在这里没有变化。
编辑
有用吗?明明这样?不,我看不出它有什么用。它 是 然而,在模板函数中很有用,有时会做类似的事情:
template <typename T>
T foo() {
if (prepare_for_for()) {
return do_foo();
} else {
return T();
}
}
这会起作用,即使是 T
== void
。
语法上void()
是用函数符号(见5.2.3)编写的显式类型转换。
请注意,即使在 "classic" C (C89/90) 中,也已经允许显式转换为 void
。当然,在 C 中,必须使用 "classic" C 风格的强制转换符号并提供一个参数。在 C 中,任何表达式都可以转换为 void
,包括已经是 void
的表达式。此功能未更改地迁移到 C++ 中显式类型转换的 cast notation(它由其功能的 static_cast
分支处理,即您可以 static_cast
到 void
在 C++ 中)。
考虑到上述情况,转换为 void
也得到替代 C++ 强制转换语法 - 函数符号 的一致支持也就不足为奇了。一旦你理解了这一点,它被扩展以支持 "argument-less" 版本就不足为奇了 - void()
.
this 在 C++ 中的用途将包括泛型函数等上下文
template <typename T>
T foo() {
...;
return T(); // remains valid even when `T == void`
}
请注意,在 C++ 中,void
函数的 return void
伪值是完全合法的。创建此类 void()
伪值的能力消除了为上述函数编写专用 void
特化的需要。
作为旁注,void()
仅在上下文强制将其解释为 表达式 时才代表显式类型转换,如您的示例所示。当上下文调用类型名称(例如 int foo(void())
或 using T = void();
)时,它实际上声明了一个 returns void
且不带参数的无名函数。