“void()”如何有用?

时间:2017-12-04 17:19:36

标签: c++ void variable-declaration

您无法声明void变量:

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

然而这编译:

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

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

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

2 个答案:

答案 0 :(得分:5)

声明

void();

创建一个空值,然后丢弃它。 (除了丢弃它或返回它之外,你实际上无法使用空值。)

standard†在5.2.3 [expr.type.conv

中说明
  

表达式T(),其中T是非数组完整对象的simple-type-specifier或typename-specifier   type或(可能是cv-qualified)void类型,创建一个指定类型的prvalue,其值为   通过值初始化(8.5)生成类型为T的对象;没有为void()case

进行初始化

请注意,它明确地提到void()是合法的。

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

修改

有用吗?明白这样吗?不,我看不到它的用途。然而,它 在模板函数中很有用,它们有时会执行以下操作:

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

即使是T == void

,这也会奏效

答案 1 :(得分:3)

语法void()是用功能表示法编写的明显类型转换(见5.2.3)。

请注意,即使在“经典”C(C89 / 90)中,也已允许对void进行显式转换。当然,在C中,必须使用“经典”C风格的演员表示法并提供一个参数。任何表达式都可以转换为C中的void,包括已经void的表达式。此功能在C ++中未更改地迁移到显式类型转换的强制转换符号(它由其功能的static_cast分支处理,即您可以static_castvoid in C ++)。

考虑到上述情况,替代C ++强制语法 - 功能表示法也始终支持转换为void并不奇怪。一旦你理解了这一点,毫不奇怪它被扩展到支持“无论证”版本 - 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并且不带参数的无名函数。