void()和void {}有什么区别? [英] What's the difference between void() and 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()
, whereT
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 typeT
; no initialization is done for thevoid()
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屋!