【问题标题】:What is the precedence of the meta-operator ...?元运算符的优先级是什么...?
【发布时间】:2011-10-25 22:49:44
【问题描述】:

元操作符... 的工作是解压模板类型参数包的优先级是多少?我想它相当低,但它有多低? C++ 标准说:

运算符的优先级不是直接指定的,但可以从语法中推导出来。

有人愿意接受挑战吗?当然,... 不会出现在 C++03 运算符优先级表中。


好的,如果... 不是运算符,那么究竟是什么确定std::forward<Args>(args)... 适用于整个序列std::forward<Args>(args) 而不仅仅是(args)

【问题讨论】:

  • 问题到底是什么?它不是操作员,不与操作员交互。也许你应该提供一个例子。
  • @Gene:我更新了问题。
  • @FredOverflow:你问的一些 C++0x 事情我知道或可以直觉,其他人(和这个)不知道。但请继续问。我正在从您的问题中学习 C++0x!就像,懒惰的鸟,在另一只之后飞翔。 :-)
  • @Alf:只要每个人都在大部队前面轮流,那就是最好的懒惰。
  • @Steve:如果我们轮流,那么我们也必须循环回答,否则就不会真正轮流。 (毕竟这是一个问答网站。)但是,就像回答一样,我想保留向那些做得最好的人提问的任务。事实证明,弗雷德提出了非常好的问题。只要我们都受益,为什么要打破这种平衡呢? :)

标签: c++ c++11 operator-precedence ellipsis variadic-templates


【解决方案1】:

好像不是运算符。来自 N3092(抱歉,我手头没有更新的草稿)

[14.5.3] 4/ 包扩展是命名一个或 更多参数包,后跟省略号。令牌序列 称为扩展模式;它的语法取决于 扩展发生的上下文。包扩展可能发生在 以下上下文:

  • 在初始化列表 (8.5) 中;模式是一个 初始化子句。
  • 在基本说明符列表 (10) 中;模式是一个基本说明符。
  • 在 mem-initializer-list (12.6.2) 中;模式是一个 内存初始化器。
  • 在模板参数列表中 (14.3);模式是一个 模板参数。
  • 在动态异常规范 (15.4) 中;模式是一个 类型 ID。
  • 在属性列表中 (7.6.1);模式是一个属性。
  • 在捕获列表中 (5.1.2);该模式是一个捕获。 [例子:

    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
    }
    

    ——结束示例]

【讨论】:

  • 这是一个很好的答案,但不幸的是并不是非常有启发性。 :-)
  • 更能说明问题的是每个案例的示例和具体案例,展示了... 的定位如何影响编译器认为您的意思。
  • @Omnifarious:标准文本在整个文本中分散了... 的不同用法。相关部分包含示例。
【解决方案2】:

根据方便的Hyperlinked C++ BNF Grammar,函数调用如下所示:

后缀表达式(表达式列表opt

表达式列表只是一个initializer-list,看起来像这样:

初始化子句 ...opt
初始化器列表,初始化器子句 ...opt

省略号是包扩展符号。

initializer-clause 反过来可以是assignment-expressionbraced-init-list

所有这一切都是说,省略号的语法优先级低于任何实际运算符,因此例如以下是等价的:

foo(args ^= 0x1234...) and foo((args ^= 0x1234)...)

foo(x ? args : 42...) and foo((x ? args : 42)...) 

【讨论】:

    猜你喜欢
    • 2018-06-21
    • 1970-01-01
    • 1970-01-01
    • 2017-10-13
    • 2016-11-18
    • 2014-03-25
    • 1970-01-01
    相关资源
    最近更新 更多