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

Why do C++ templates use the angle bracket syntax?

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

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

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++历史上有人well-versed能挖掘出使用尖括号的最初设计原理吗?或者,您能否说明为什么其他解决方案效果不佳?

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

The <…> brackets are used in preference to the parentheses (…) partly to emphasize the different nature of template arguments (they will be evaluated at compile time) and partly because parentheses are already hopelessly overused in C++.

9.2. <…> vs (…)

But why use brackets instead of parentheses? As mentioned before, parentheses already have many uses in C++. A syntactic clue (the <…> brackets) can be usedful for reminding the user about the different nature of the type parameters (they are evaluated at compile time). Furthermore, the use of parentheses could lead to pretty obscure code:

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?

These problems would become a serious practical concern if the notation for explicit disambiguation of overloaded function calls were adopted. The chosen alternative seems much cleaner:

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] 相同的方式将 <…> 放在变量名称之后 来反对 (…),尽管此位置从未在本文的其他地方使用过。

他的论点"using (…) can lead to obscure/ambiguous code"仍然有效。正如这个问题的评论中提到的,使用括号 T(x) 会导致函数类型或函数调用的歧义(请注意 T 可以是函数模板,C++ 允许值作为模板参数)。

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

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