简体   繁体   中英

What's the difference between void() and void{}?

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;
}

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);
}

The output is void f(T) [with T = void*] .

[expr.type.conv]

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. [...]

NB void is a simple-type-specifier .

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.

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

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

Incompletely-defined object types and the void types are incomplete types (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() 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.


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

otherwise, decltype(e) is the type of e

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

Therefore, decltype(void()) yields void .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM