void()和void {}有什么区别? [英] What's the difference between void() and void{}?

查看:49
本文介绍了void()和void {}有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Basically, I'd like to know why the compiler rejects ptr2 declaration:

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

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

如果您认为 ptr1 是函数指针,请查看此代码:

Take a look at this code if you think that ptr1 is a function pointer:

#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 *] .

推荐答案

[expr.type.conv]

[expr.type.conv]

2表达式 T(),其中 T 简单类型说明符类型名称说明符对于非数组完整对象类型或(可能是 cv 限定) void 类型,创建指定类型的prvalue,其值是由value-初始化(8.5)类型为 T 的对象;对于 void()情况,不会进行任何初始化.[...]

2 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 简单类型说明符.

3同样,简单类型说明符类型名称说明符后跟 braised-init-list 创建一个临时对象使用指定的 braised-init-list 指定类型的直接列表初始化(8.5.4),其值是该临时对象作为prvalue.

3 Similarly, a simple-type-specifier or typename-specifier followed by a braced-init-list creates a temporary object of the specified type direct-list-initialized (8.5.4) with the specified braced-init-list, and its value is that temporary object as a prvalue.

感谢基思·汤普森指出,在其中创建了临时对象/3,而是在/2中创建的.

Thanks to Keith Thompson for pointing out that a temporary object is created in /3, whereas a value is created in /2.

当我们看[basic.types]/5

When we take a look at [basic.types]/5

未完全定义的对象类型和 void 类型是不完全类型(3.9.1).对象不得定义为不完整的类型.

Incompletely-defined object types and the void types are incomplete types (3.9.1). Objects shall not be defined to have an incomplete type.

现在很明显,不允许 void {} ,因为它会创建(临时)对象. void()但是,"only"会创建一个(pr)值.我认为这两种情况的实现方式(行为)没有区别,但是不同的语言规则适用于它们.这些规则之一禁止创建 void 类型的对象,因此会出错.

It now becomes clear that void{} is not allowed as it would create a (temporary) object. void() however "only" creates a (pr)value. I don't think there's a difference in the implementation (behaviour) for those two cases, but different language rules apply to them. One of those rules forbids creation of an object of type void, hence the error.

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

Ad decltype(void()): decltype(e) takes an expression e. In [dcl.type.simple]/4, the applicable definition of decltype(e) is:

否则, decltype(e) e

(因为 void()会产生prvalue,而不是 id-expression ).

(as void() yields a prvalue and is not an id-expression).

因此, decltype(void())产生 void .

这篇关于void()和void {}有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆