开发者

What is the precedence of the meta-operator ...?

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)...) 
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜