元运算符...的优先级是什么?

发布于 2024-11-29 10:36:49 字数 388 浏览 2 评论 0 原文

负责解压模板类型参数包的元运算符 ... 的优先级是什么?我认为这个数字相当低,但到底低到什么程度呢? C++ 标准说:

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

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


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

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, ... 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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

萌化 2024-12-06 10:36:49

看来不是运营商啊来自 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);该模式是一个捕获。 [示例:

    模板<类...类型> void f(类型...其余);
    模板<类...类型> void g(类型...其余) {
        f(&休息...); // “&rest ...”是一个包扩展; “&rest”是它的模式
    }
    

    —结束示例]

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]

橪书 2024-12-06 10:36:49

根据方便的 超链接 C++ BNF 语法,函数调用如下所示:

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

expression-list 只是一个 初始化列表,如下所示:

初始化子句...opt
初始值设定项列表、初始值设定项子句...opt

其中省略号是包扩展符号。

反过来,初始化子句可以是赋值-表达式braced-init-list

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

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

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

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)...) 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文