What is the precedence of the meta-operator ...
whose job is to unpack template type parameter packs? I imagine it's pretty low, but how low is it? The C++ standard says:
The precedence of operators is not directly specified, but it can be derived from the syntax.
Anyone up for the challenge? Of course, 开发者_StackOverflow...
does not appear in C++03 operator precedence tables.
Okay, if ...
is not an operator, what exactly determines that std::forward<Args>(args)...
applies to the the entire sequence std::forward<Args>(args)
and not just (args)
, for example?
It doesn't seem to be an operator. From N3092 (sorry I don't have a more recent draft handy)
[14.5.3] 4/ A pack expansion is a sequence of tokens that names one or more parameter packs, followed by an ellipsis. The sequence of tokens is called the pattern of the expansion; its syntax depends on the context in which the expansion occurs. Pack expansions can occur in the following contexts:
- In an initializer-list (8.5); the pattern is an initializer-clause.
- In a base-specifier-list (10); the pattern is a base-specifier.
- In a mem-initializer-list (12.6.2); the pattern is a mem-initializer.
- In a template-argument-list (14.3); the pattern is a template-argument.
- In a dynamic-exception-specification (15.4); the pattern is a type-id.
- In an attribute-list (7.6.1); the pattern is an attribute.
In a capture-list (5.1.2); the pattern is a capture. [Example:
template<class ... Types> void f(Types ... rest); template<class ... Types> void g(Types ... rest) { f(&rest ...); // “&rest ...” is a pack expansion; “&rest” is its pattern }
— end example]
According to the handy Hyperlinked C++ BNF Grammar, a function call looks like this:
postfix-expression ( expression-listopt )
expression-list is just an initializer-list, which looks like this:
initializer-clause ...opt
initializer-list , initializer-clause ...opt
where the ellipses are the pack expansion notation.
initializer-clause, in turn, can be either assignment-expression or braced-init-list.
All this is to say, then, that the ellipsis has a lower grammatical precedence than any actual operator, so for instance the following are equivalent:
foo(args ^= 0x1234...) and foo((args ^= 0x1234)...)
foo(x ? args : 42...) and foo((x ? args : 42)...)
精彩评论