构造一个空洞类型

Construction of a void Type?

本文关键字:一个 空洞 类型      更新时间:2023-10-16

我得到了一段使用void()作为参数的代码。代码未编译。。。明显地

我们可以实例化void类型的任何东西吗?我认为答案是否定的,除了void*。例如:

  1. 写入函数void askVoid(void param) {}错误:

参数可能没有void类型的

  1. 编写函数void askNaught() {}并使用askNaught(void())`errors调用它:

错误C2660:takeNaught:函数不接受1个参数

  1. 编写模板化函数template <typename T> void takeGeneric(T param) {}并用takeGeneric(void())错误调用它:

错误C2893:无法专门化函数模板void takeGeneric(T)

  1. 声明void voidType错误:

不允许类型不完整

  1. 声明auto autoVoid = void()错误:

无法推导出auto

  1. 声明void* voidPtr工作正常,但remove_pointer_t<decltype(voidPtr)> decltypeVoid错误:

错误C2182:decltypeVoid:非法使用类型void

就是这样,对吧?在C++中没有void()的位置,是吗?这只是给我的坏代码,对吧?

表达式void()void类型的prvalue,可以在任何可能使用该表达式的地方使用,它[basic.basic]/9提供了一个列表:

  • 作为表达式语句:void();
  • 作为条件运算符的第二个或第三个操作数:true ? throw 1 : void()
  • 作为逗号运算符的操作数:++it1, void(), ++it2
  • 作为decltypenoexcept:using my_void = decltype(void()); static_assert(noexcept(void()), "WAT");的操作数
  • 在函数的return语句中返回(可能是cv限定的)void:const void f() { return void(); }
  • 作为显式转换为(可能是cv限定的)void:static_cast<const void>(void())的操作数

类型为void的表达式也可以用作typeid的操作数,但在此上下文中,void()尤其会被解析为类型,而不是表达式。

C++(我说C++,而不是C)允许具有void返回类型的(§6.6.3逗号2)函数返回void表达式,即:

void foo() { return void(); }

但请注意,它是而不是构建临时void

您可以将void()作为函数参数:

void test(void()) { ... }

扩展到:

void test(void (*)())

它是一个函数指针,指向一个返回void且不带参数的方法。

完整示例:

void abc() {}
void test(void()) { }
int main() {
test(abc);
}

您可以使用void()作为可调用类型,例如std::function<void()> f;是一个有效的语句。

此外,从8.3.5/4:

由非依赖类型void的单个未命名参数组成的参数列表等效于空参数列表。

这意味着这是有效的:

template<typename T>
struct F;
template<typename R, typename... A>
struct F<R(A...)> { };
int main () {
F<void(void)> s;
}

在这里,您没有实例化void类型的任何东西,而是将其用作(比方说)可调用类型的参数列表。

不确定这是否回答了你的问题,我不清楚这个问题到底是什么。

C++中没有void()的位置,是吗?

作为一个表达式,void()在C++中是有效的。

从标准来看,$5.2.3/2 Explicit type conversion (functional notation) [expr.type.conv]:

表达式T(),其中T是简单类型说明符或非数组完整对象类型的typename说明符或(可能是cv限定的)void类型,创建指定的prvalue类型,其值是通过值初始化(8.5)CCD_ 47类型的对象;对于CCD_ 48的情况不进行初始化。

来自cppreference.com:

new_type()

如果new_type是对象类型,则该对象被值初始化;否则,不进行初始化。如果new_type是(可能cv限定)void,则表达式是voidprvalue。