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

后端 未结 1 1005
耶瑟儿~
耶瑟儿~ 2021-01-12 01:22

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

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

    // t         


        
相关标签:
1条回答
  • 2021-01-12 02:06

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

    N.B. 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.

    0 讨论(0)
提交回复
热议问题