[英]What's the difference between void() and void{}?
Basically, I'd like to know why the compiler rejects ptr2
declaration: 基本上,我想知道为什么编译器拒绝
ptr2
声明:
int main() {
// this one works
decltype(void())* ptr1;
// this one does not
decltype(void{})* ptr2;
}
Take a look at this code if you think that ptr1
is a function pointer: 如果您认为
ptr1
是函数指针,请看以下代码 :
#include <iostream>
using namespace std;
template <class T>
void f(T t) {
cout << __PRETTY_FUNCTION__ << endl;
}
int main() {
decltype(void())* ptr;
f(ptr);
}
The output is void f(T) [with T = void*]
. 输出为
void f(T) [with T = void*]
。
[expr.type.conv] [expr.type.conv]
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
;2表达
T()
其中T
是一个简单的类型说明符或类型名称说明符用于非阵列的完整对象类型或(可能CV -qualified)void
型,创建指定类型的prvalue,其值是通过值初始化(8.5)一个类型为T
的对象而产生的结果; no initialization is done for thevoid()
case.对于
void()
情况,不会进行任何初始化。 [...][...]
NB void
is a simple-type-specifier . NB
void
是一个简单类型说明符 。
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同样地,一个简单型或说明符 类型名称说明符后跟一个支撑-INIT列表与指定掺进-INIT列表创建指定的类型的直接清单初始化(8.5.4)的临时对象,并且其value是该临时对象作为prvalue。
Thanks to Keith Thompson for pointing out that a temporary object is created in /3, whereas a value is created in /2. 感谢Keith Thompson指出在/ 3中创建了一个临时对象 ,而在/ 2中创建了一个值 。
When we take a look at [basic.types]/5 当我们看一下[basic.types] / 5
Incompletely-defined object types and the
void
types are incomplete types (3.9.1).不完全定义的对象类型和
void
类型是不完全类型(3.9.1)。 Objects shall not be defined to have an incomplete type.对象不应定义为不完整的类型。
It now becomes clear that void{}
is not allowed as it would create a (temporary) object. 现在很清楚,不允许
void{}
因为它会创建(临时)对象。 void()
however "only" creates a (pr)value. void()
但是“仅”创建一个(pr)值。 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. 这些规则之一禁止创建类型为
void
的对象,因此是错误。
Ad decltype(void())
: decltype(e)
takes an expression e
. Ad
decltype(void())
: decltype(e)
采用表达式e
。 In [dcl.type.simple]/4, the applicable definition of decltype(e)
is: 在[dcl.type.simple] / 4中,
decltype(e)
的适用定义为:
otherwise,
decltype(e)
is the type ofe
否则,
decltype(e)
是的类型e
(as void()
yields a prvalue and is not an id-expression ). (因为
void()
产生prvalue,而不是id-expression )。
Therefore, decltype(void())
yields void
. 因此,
decltype(void())
产生void
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.