【问题标题】:C++ Templates Angle Brackets Pitfall - What is the C++11 fix?C++ 模板尖括号陷阱 - 什么是 C++11 修复?
【发布时间】:2013-04-03 10:58:50
【问题描述】:

在 C++11 中,这是现在有效的语法:

vector<vector<float>> MyMatrix;

而以前,它必须这样写(注意空格):

vector<vector<float> > MyMatrix;

我的问题是标准使用什么修复来允许第一个版本?

是否可以像将&gt; 设为令牌而不是&gt;&gt; 一样简单?如果不是这样,那么这种方法有什么不适用的?

我认为像myTemplate&lt; x&gt;&gt;3 &gt; 这样的形式没有问题,因为您可以通过myTemplate&lt;(x&gt;&gt;3)&gt; 来消除它们的歧义。

【问题讨论】:

  • &gt;已经一个令牌,但解析器是并且是贪婪的。因此,修复必须看起来不同。 – 一种可能性当然是让&gt;&gt;成为一个令牌。
  • 我猜你正在寻找 §14.2.3: "当解析模板参数列表时,第一个非嵌套 > 被视为结束分隔符而不是更大- than 运算符。类似地,第一个非嵌套的 >> 被视为两个连续但不同的 > 标记,其中第一个作为模板参数列表的结尾并完成模板 ID。"
  • “标准用于允许第一个版本的修复是什么” - 我相信这与 标准 无关。我的意思是 - 实施。我相信这是编译器决定如何实现这个要求,由标准强制。
  • @KirilKirov:标准改变了对 C++ 源代码进行标记的规则。从标准作者的观点来看,这是他们所做的“修复”。如何编写代码以匹配新的(更加上下文敏感的)标记化规则取决于实现者。
  • @KonradRudolph 在此处查看我的第二个问题的改写:stackoverflow.com/questions/15785496#comment22443479_15785583(对 Mike Seymour 的回答发表评论)。

标签: c++ parsing templates tokenize


【解决方案1】:

通过在解析模板参数时在解析规则中添加一个特殊情况来修复它。

C++11 14.2/3:在解析 template-argument-list 时,第一个非嵌套的 &gt; 被视为结束分隔符,而不是大于运算符。同样,第一个非嵌套的&gt;&gt; 被视为两个连续但不同的&gt; 令牌,其中第一个作为template-argument-list 的末尾并完成模板ID

【讨论】:

  • 这看起来像一个缺陷。 IIRC,其目的是像template &lt;int i&gt; class X{}; X&lt;(10 &gt;&gt; 2)&gt;(带有额外的括号)这样的东西是合法的。
  • @JamesKanze “非嵌套”部分是否涵盖了这一点?
  • @Norswap 我错过了那部分。在上下文中,我希望“嵌套”仅指 &lt;...&gt; 类型括号,但这并没有真正意义,所以它一定是。
  • @Norswap 这是一个有趣的想法。目前没有(一元或二元)运算符包含多个标记。然而,在更大的表达式上下文中,像std::vector 这样的东西由三个标记组成,但就像一个元素一样工作。 (我认为对单个运算符使用两个标记会导致递归下降解析器出现问题。在 yacc 中敲击 C++ 表达式的语法会很有趣,看看是否将其更改为使用两个 '&gt;' 标记作为单个运算符会导致冲突。
  • @Norswap:“我的建议不应该造成任何我能看到的问题。”但是,您(或其他任何人)不能立即看到任何问题是不够的。要改变语法的一个基本方面(运算符是一个标记),并可能对整个语言产生影响,您需要做很多工作来证明您没有引起任何问题。独立的特殊情况更容易验证,即使它确实很难看。
猜你喜欢
  • 1970-01-01
  • 2017-09-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-14
  • 1970-01-01
  • 2011-12-13
  • 2011-10-15
  • 1970-01-01
相关资源
最近更新 更多