为什么C ++模板使用尖括号语法?

时间:2017-04-06 11:35:00

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

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

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

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

仅在C ++ 11中得到修复。我没有看到引入额外语法的理由,可以说,圆括号在保持变化极简主义的同时可以起到同样的作用。你可以使用

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 ++历史的人能否挖掘出使用尖括号的原始设计理念?或者,你能说明为什么其他解决方案也不会有效吗?

1 个答案:

答案 0 :(得分:96)

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

  

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

     

...

     

9.2。 <…> vs (…)

     

但为什么要使用括号而不是括号?如前所述,括号在C ++中已经有很多用途。语法线索(<…>括号)可用于提醒用户类型参数的不同性质(它们在编译时评估)。此外,括号的使用可能导致相当模糊的代码:

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]相同,以反对(…),尽管此展示位置从未使用过本文其他地方。

他的论点“使用(…)可能导致模糊/模糊的代码”仍然有效。正如本问题的评论中所提到的,使用括号T(x)会导致函数类型或函数调用模糊不清(请注意T可以是函数模板,C ++允许值是模板参数。)

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

我不明白为什么T{x}无法使用,也许根本就没有考虑过,或者在任何地方都使用{…}可能太难看了。