解析 - 为什么 C++ 在模板 var decls 上有问题而 java 在通用 var decls 上却没有?

Parsing - Why C++ has trouble with template var decls and java doesn't with generic var decls?

在C++中,如果我写a < b > c,意思可以是表达式语句(a < b) > c,也可以是a<b>类型变量c的声明。

为什么这在 java 中不是问题? (a < b) > c 选项是否被泛型废弃了,因为尽管它进行了解析,但它总是以类型错误告终? C++ 是否坚持保留此选项以实现向后兼容性?

两种语言中的真值和假值之间存在细微差别。

In Java (a < b) > c 将是布尔值和 c 之间的比较,即使 c 也是布尔值也没有多大意义。由于 Java 没有运算符重载,所以不会出现 (a < b) > c 不能写成 (a < b) != c.

的情况

另一方面,在 C++ 中,运算符重载允许您将完全不同的语义分配给 <>。因此,a < b 可能根本不是布尔值。

对于 C++ 或 Java,由于不同的原因,这并不是真正的问题。

在Java中,a < b > c;只能是声明,因为不能是任意表达式expression statements。可能的表达式语句列表不包括比较或算术表达式(pre/post increment/decrement 除外),因此该语句必须是局部声明,并且在该上下文中 a 必须是泛型类型。

在 C++ 中,如果 < 跟在已声明为模板的标识符之后,则它只能是模板括号,并且该声明需要先于标识符的使用。虽然这不是特别干净的设计(它需要一个上下文相关的解析器),但这个问题已经存在于 C 中,如果不知道标识符是否是类型别名就无法正确解析。 [注 1] 这基本上需要让词汇扫描器访问符号 table,并确保符号 table 至少包含有关“种类”的准确信息(尽管 type/class ) 每个标识符。


备注

  1. 正如 Ira Baxter 指出的那样,上下文相关解析的替代方法是使用 GLR(或等效)解析引擎执行上下文无关解析,该引擎保留所有可能的解析。然后可以在解析之后通过语义分析来解决歧义。这当然是一种 acceptable 策略,但我不认为这是语言设计者所考虑的策略,他们认为在使用之前声明类型和模板很重要。