【问题标题】:Parsing - Why C++ has trouble with template var decls and java doesn't with generic var decls?解析 - 为什么 C++ 对模板 var decls 有问题,而 java 对通用 var decls 没有问题?
【发布时间】:2023-04-01 23:18:01
【问题描述】:

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

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

【问题讨论】:

  • 意思是可以是,但具体的问题是什么?如果编译器可以告诉 a 是一个模板,它工作正常
  • 即使编译了,a < b > c 也不会像它看起来那样工作。
  • @RustyX - 在我看来,如果 a 小于 b,则有人想将 c 与 1 进行比较,如果不是,则将其与 0 进行比较;)
  • 因为 Java 没有模板 var decls。
  • @tohava:我真傻。我要去official Java language specification。显然,一些随机的在线黑客更权威。

标签: java c++ parsing syntax compiler-construction


【解决方案1】:

出于不同的原因,对于 C++ 或 Java 来说,这都不是问题。

在 Java 中,a < b > c; 只能是声明,因为任意表达式不能是 expression statements。可能的表达式语句列表不包括比较或算术表达式(除了前/后递增/递减),因此该语句必须是本地声明,并且在该上下文中a 必须是泛型类型。

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


注意事项

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

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

    • 仍然没有解释为什么cpp没有废弃a c。如果没有更好的答案出现,我会接受。反正我只是投了赞成票。
    猜你喜欢
    • 2010-10-27
    • 2011-03-21
    • 2019-05-19
    • 2011-08-29
    • 1970-01-01
    • 2019-11-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多