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