C++中的模板、Java 中的泛型和 >> 位移运算符

Templates in C++, Generics in Java and the >> bit shift operator

本文关键字:gt 运算符 泛型 Java C++      更新时间:2023-10-16

我的实际问题如下:

在C++中,嵌套参数之间需要有一个空格,如List< List<String> >。这样做使得编译器可以区分上述和比特移位>>。但同样的情况并非如此,因为Java List<List<String>>是完全有效的。JVM如何区分上述移位和>>位移位?

区别在于围绕假定>>运算符的上下文。当它是一个运算符时,两个操作数都需要一个表达式:

EXPR >> EXPR

表达式可以是变量、文字、函数调用或所有这些元素的复杂组合。然而,在列表声明的情况下,不涉及任何表达式,只涉及类型和id。例如:

List<List<string >> id;

事实上,在新的标准中,C++编译器也能够发挥作用。

C++中的直接问题是模板参数实际上可能包括表达式:常量表达式是完全有效的模板参数。我不认为这在Java中是真的。下面是一个表达式会把事情搞砸的例子:

std::list<std::bitset<32 >> 2> > list_of_bitset8s;

也就是说,最初的规则主要是为了保留现有的C++解析器,这些解析器倾向于使用相对简单的词法分析,而词法分析基本上是建立在上下文无关的正则表达式之上的。此外,当添加模板时,没有人真正预料到嵌套模板会被大量使用。事实证明,它们是合法的,C++2011通过允许在没有插入空格的情况下使用闭合尖括号解决了这个问题。为了消除歧义,必须使用使用右移运算符的表达式作为模板参数的罕见情况下的括号,即上述声明在C++2003中是合法的,在C++2011中是非法的。它必须被取代

std::list<std::bitset<(32 >> 2)>> list_of_bitset8s;

(好吧,如果需要,闭合角括号可以继续使用空格)。

当然,这是一个不完整的修复,因为以下仍然是非法的:

::std::list<::std::bitset<8>> list of bitset8s;

在Java中,像<<这样的运算符不能被程序员重载。因此,<<运算符有效的地方的数量比C++中的要有限得多,编译器在源代码中看到"<<"时总能弄清楚它的意思。