I can do this inside decltype()
:
auto g() -> decltype(1, "", true, new int);
But not this:
template <class... Args>
auto g(Args&&... args) -> decltype(args...);
It fails because a pack expansion appears inside decltype()
but I thought a pack expansion would result in a comma separated list of arguments. So the return type of g(a, b, c)
would be decltype(c)
because of how the comma operator works (it returns the last element). It works when you expand inside a function parameter list, template parameter list, initializer list, etc. But why here is this not the case?
Parameter packs are only expanded under certain circumstances. You can find them in the standard by searching for "pack expansion". For example,
A function parameter pack is a pack expansion (14.5.3).
(8.3.5/14).
Unless it is explicitly specified somewhere that a pack expansion occurs in a particular context, it doesn't happen, and is usually forbidden by the grammar (i.e., syntactically incorrect). For example, decltype
requires an expression as its operand. 1, "", true, new int
is indeed an expression (the ,
is the comma operator) but args...
is not an expression. However, args...
is an expression-list, so it may be used, e.g., in a function call.