This is a follow-up of this question, more precisely of the comments of this answer.
What does the void()
in decltype(void())
represent exactly?
Does it represent a function type, an expression or whatever?
When used for a function's parameter list, void specifies that the function takes no parameters. When used in the declaration of a pointer, void specifies that the pointer is "universal." If a pointer's type is void* , the pointer can point to any variable that's not declared with the const or volatile keyword.
In the C++ programming language, decltype is a keyword used to query the type of an expression. Introduced in C++11, its primary intended use is in generic programming, where it is often difficult, or even impossible, to express types that depend on template parameters.
Using a hyperlinked C++ grammar, the parsing of decltype(void())
is:
decltype( expression ) decltype( assignment-expression ) decltype( conditional-expression )
... lots of steps involving order of operations go here ...
decltype( postfix-expression ) decltype( simple-type-specifier ( expression-listopt ) ) decltype( void() )
So void()
is a kind of expression
here, in particular a postfix-expression
.
Specifically, quoting section 5.2.3 [expr.type.conf] paragraph 2 of the 2011 ISO C++ standard:
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, which is value-initialized (8.5; no initialization is done for thevoid()
case).
So void()
is an expression of type void
, just as int()
is an expression of type int
(with value 0
). Clearly a void expression has no value, but here it's the operand of decltype
, so it's not evaluated. decltype
refers only to its operand's type, not its value.
decltype(void())
is simply a verbose way of referring to the type void
.
I'm quoting the comment of @JoachimPileborg that seems to explain it correctly:
I think I figured it out now, decltype needs an expression, and not a type. void() is not actually a type here, but an expression, a C-style cast (just like e.g. int(12.34)) void(void) is not an expression therefore it doesn't work. How the compiler parses different things depends on the context, when it expects a type it parses as a type, when it expects an expression it parses as an expression. sizeof() (with the parentheses) expects first of all a type, otherwise it's parsed as a parenthesized expression.
I'm not looking for credits or reputation.
Anyway, I guess that was an interesting answer in the answer that is worth of a dedicated question for future readers.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With