我一直想知道这件事已经有一段时间了。已经有很多它们可以超载,那么为什么不到最后并允许自定义运营商呢?我认为这可能是一个很好的补充。
我被告知这会使语言难以编译。这让我想知道,C ++无论如何都不能真正设计用于简单的编译,所以它真的可以撤销吗?当然,如果你使用带有静态表和语法的LR解析器,例如
E → T + E | T
T → F * T | F
F → id | '(' E ')'
它不起作用。在Prolog中,通常使用运算符优先级解析器AFAIK进行解析,可以轻松定义新的运算符,但语言更简单。现在,显然可以重写语法,以便在操作符被硬编码到语法中的每个地方接受identifiers
。
还有哪些其他解决方案和解析器方案以及其他哪些因素影响了设计决策?
答案 0 :(得分:10)
http://www2.research.att.com/~bs/bs_faq2.html#overload-operator
这种可能性已被多次考虑过,但每次我/我们认为可能的问题超过了可能的好处。
这不是语言技术问题。即使我在1983年首次考虑它,我也知道它是如何实现的。然而,我的经验是,当我们超越最微不足道的例子时,人们似乎对运营商使用的“明显”含义有着微妙的不同看法。一个经典的例子是
a**b**c
。假设已**
表示取幂。我应该a**b**c
表示(a**b)**c
还是a**(b**c)
?我认为答案很明显,我的朋友们同意了 - 然后我们发现我们不同意哪个决议是明显的。我的猜想是,这些问题会导致细微的错误。
答案 1 :(得分:2)
编译比现有编译更难。此外,运营商的优先权会出现问题:您如何定义它?您需要一种方法来告诉编译器用户定义的运算符优先于另一个运算符。
几乎可以肯定它是可行的,但我认为C ++不需要其他方式来拍摄自己的脚: - )
答案 2 :(得分:1)
这会使语言变得更加复杂。这显然不可取。
不过,请查看Boost Spirit。使用大量的模板元编程技巧可以使你提到的东西变得很长。
答案 3 :(得分:0)
实际上它的设计非常容易解析和编译。 C有32个定义的关键字,所有其他标记都是函数和变量。
C ++只有一些。人们可以很容易地识别哪个令牌是哪个,因此知道当使用+令牌或其他什么时要查找什么。
答案 4 :(得分:0)
允许自定义运算符的问题是您还必须允许程序员指定运算符应该如何使用的语法。我想C ++类型系统可以帮助一点,但它有助于解决关联性等问题。
它会使已经很复杂的语言变得复杂得多......
答案 5 :(得分:0)
通常可以避免这种情况,因为大多数代码都是由一个人编写的,因此代码应该是“可审阅的”,并且它几乎不是语言的“所需”功能。
乔尔·斯波尔斯基对此有一个good article。
答案 6 :(得分:0)
我刚刚发现它实际上可以实现与重载运算符非常相似的东西。考虑
Vector v, a, b; v = a /vectorProduct/ b;
事实证明,您可以通过使用现有运算符分隔的虚拟类来实现自定义运算符的行为。 =)