【问题标题】:Why do C++ templates use the angle bracket syntax?为什么 C++ 模板使用尖括号语法?
【发布时间】:2017-09-01 09:59:06
【问题描述】:

名义上的问题是指在 1990 年左右引入模板的 C++ 标准中的设计决策。

为什么设计师使用<>(尖括号)而不是()(圆括号)?这样做可以让很多程序员免于与位移相关的错误

std::vector<std::vector<int>> // does not work until C++11

仅在 C++11 中得到修复。我看不出引入类似这样的附加语法的理由,可以说,圆括号可以达到相同的目的,同时保持更改的最小化。 Insted 你可以使用

template(typename T) // Define template if round brackets could be used
mytemplate { ... }
...
...
mytemplate(mytemplate(int)) obj; //Instantiate template when round brackets could be used

精通 C++ 历史的人能否找出使用尖括号的原始设计原理?或者,您能否说明为什么其他解决方案效果不佳?

【问题讨论】:

  • 因为函数指针。 int(int(int)) obj; 将使 obj 成为一个指向函数的指针,该函数返回 int 并获取指向返回 int 并获取 int 的函数的指针。或类似的东西。
  • 圆括号对函数模板的影响更大:在template_function(int())() 中,int() 是模板参数还是函数参数?
  • @ysc 假设 unicode,有数十亿个替代字符。我们应该一个一个地覆盖它们吗?在每种情况下都必须证明它比&lt;&gt; 更糟吗?几乎可以肯定,这不是用于决定 &lt;&gt; 的过程:描述整个过程对于 SO 来说太宽泛了。其他任何东西都是意见、简化或谎言。简短的回答是“这就是标准化的,这就是我们使用它的原因”。我怀疑那会满足。 OP需要几分钟吗?当时委员会成员的回忆?
  • @Yakk - Unicode 不是一个选项,因为 C++ 是在人们主要使用 ASCII 进行编程时设计的。因此,只有括号或 {} 或 [] 具有替代匹配符号,并且它们至少都有同样的问题。
  • 值得指出的是,D 使用了TemplatedType!(T),它没有歧义问题,因为在 C++ 中没有二进制的!

标签: c++ c++11 language-design template-meta-programming


【解决方案1】:

Bjarne Stroustrup 于 1988 年在 USENIX 论文 Parameterized Types for C++ 中介绍了模板,后来并入了 1990 年出版的The Annotated C++ Reference Manual(标准化 C++ 之前的版本)。根据论文,

&lt;…&gt; 括号优先于括号 (…) 使用,部分原因是 强调模板参数的不同性质(它们将在编译时评估),部分原因是 括号在 C++ 中已经无可救药地过度使用了

9.2。 &lt;…&gt;(…)

但是为什么要使用方括号而不是圆括号呢?如前所述,括号在 C++ 中已经有很多用途。句法线索(&lt;…&gt; 括号)可用于提醒用户类型参数的不同性质(它们在编译时评估)。此外,使用括号可能会导致代码非常晦涩:

template(int sz = 20) class buffer {
    buffer(int i = 10);
    // ...
};
buffer b1(100)(200);
buffer b2(100);      // b2(100)(10) or b2(20)(100)?
buffer b3;           // legal?

如果采用显式消歧重载函数调用的表示法,这些问题将成为一个严重的实际问题。选择的替代方案似乎更干净:

template<int sz = 20> class buffer {
    buffer(sz)(int i = 10);
    // ...
};
buffer b1<100>(200);
buffer b2<100>;      // b2<100>(10)
buffer b3;           // b3<20>(10)
buffer b4(100);      // b4<20>(100)

论文还解释了为什么使用templateclass 关键字。

请注意,Stroustrup 以与int x[10] 相同的方式将&lt;…&gt; 置于变量名之后 以反对(…),尽管此位置从未在本文的其他地方使用。

他关于“使用(…) 会导致代码模糊/模棱两可”的论点仍然有效。正如这个问题的评论中提到的,使用括号 T(x) 会导致函数类型或函数调用不明确(注意 T 可以是函数模板,而 C++ 允许值作为模板参数)。

同样,使用方括号 T[x] 会导致数组类型或索引不明确。

我不明白为什么还不能使用T{x},可能是根本没有考虑,或者可能太丑了,不能到处使用{…}

【讨论】:

  • "我不明白为什么 T{x} 还不能使用" 现在它被用于新型构造,所以无论如何都不适用于模板。 ideone.com/0cADl9
  • @JAB 是的,它在 2011 年肯定是模棱两可的,但我看不出有理由在 1988 年拒绝它。除非新式构造语法实际上是在 30 年前计划好的^_^。跨度>
  • 好吧,{} 那时已经有两种用途(用于块和旧式初始化程序),因此虽然可能不会有任何语法歧义,但程序员会更加困惑。
  • 感谢您挖掘本文,包括实际演示。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-09-14
  • 1970-01-01
  • 1970-01-01
  • 2021-11-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多