"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_castvoid 在 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 且不带参数的无名函数。