void()和void {}之间有什么区别?

时间:2013-09-22 21:33:04

标签: c++ c++11

基本上,我想知道为什么编译器会拒绝ptr2声明:

int main() {
    // this one works
    decltype(void())* ptr1;

    // this one does not
    decltype(void{})* ptr2;
}

如果您认为ptr1是函数指针,请查看this code

#include <iostream>
using namespace std;

template <class T>
void f(T t) {
    cout << __PRETTY_FUNCTION__ << endl;
}

int main() {
    decltype(void())* ptr;
    f(ptr);
}

输出为void f(T) [with T = void*]

1 个答案:

答案 0 :(得分:11)

[expr.type.conv]

  

2表达式{​​{1}},其中T()简单类型说明符 typename-specifier ,用于非数组完整对象type或(可能是 cv -qualified)T类型,创建一个指定类型的prvalue,其值是value-initializing(8.5)类型为{{1}的对象生成的值}};没有为void情况进行初始化。 [...]

N.B。 T 简单类型说明符

  

3同样,简单类型说明符 typename-specifier 后跟 braced-init-list 会创建一个临时对象指定的类型direct-list-initialized(8.5.4)与指定的 braced-init-list ,其值是临时对象作为prvalue。

感谢Keith Thompson指出在/ 3中创建了临时对象,而在/ 2中创建了

当我们看一下[basic.types] / 5

  

未完全定义的对象类型和void()类型是不完整类型(3.9.1)。对象不应被定义为具有不完整的类型。

现在很清楚,void是不允许的,因为它会创建一个(临时)对象。 void但是“仅”会创建(pr)值。我不认为这两种情况的实现(行为)存在差异,但不同的语言规则适用于它们。其中一条规则禁止创建void{}类型的对象,因此错误。


广告void()void采用表达式decltype(void())。在[dcl.type.simple] / 4中,decltype(e)的适用定义是:

  

否则,edecltype(e)

的类型

(因为decltype(e)产生一个prvalue而不是 id-expression )。

因此,e会产生void()

相关问题