【问题标题】:Operator vs functions behaviour运算符与函数的行为
【发布时间】:2013-07-20 21:31:02
【问题描述】:

我正在阅读以下文档,

https://code.google.com/p/go-wiki/wiki/GoForCPPProgrammers

发现下面的说法有点模棱两可:

与 C++ 不同,new 是一个函数,而不是一个运算符; new int 是语法错误。

在 C++ 中,我们将运算符实现为函数,例如+ 使用 operator+

那么,operatorfunction 在一般编程语言中的确切区别是什么?

【问题讨论】:

  • a+ba.operator+(b) 都可以写——运算符是语法糖。
  • 没错。但是问题中已经提到了这个事实!与此无关的问题。
  • 报价的哪一部分你不明白?目前尚不清楚您真正要问的是什么。
  • 运算符是语言语法的一部分。函数使用多个运算符来做事。或类似的东西。

标签: c++ syntax go operator-overloading new-operator


【解决方案1】:

函数和运算符之间的实际区别取决于编程语言。在纯 C 中,运算符是语言本身的一部分。不能添加操作员,也不能更改现有操作员的行为。 C++ 的情况并非如此,它的运算符被解析为函数。

从完全不同的角度来看,考虑 Haskell,其中任何(二元)函数都可以被视为二元运算符:

如果您不会说 Haskell,但知道点积,那么这个例子应该仍然相当简单。给定:

dotP :: (Double, Double) -> (Double, Double) -> Double
dotP (x1, y1) (x2, y2) = x1 * x2 + y1 * y2

两者

dotP (1,2) (3,4)

(1,2) `dotP` (3,4)

会给 11 个。

解决 Go 文档中的引用:Go 开发人员只是强调,在 C++ 中,人们会将 new 视为具有自己语法的关键字,而在 Go 中应该将 new 视为任何其他函数。

【讨论】:

    【解决方案2】:

    虽然我仍然认为这个问题基本上是 Difference between operator and function in C++? 的重复,但在你引用的特定上下文中澄清差异意味着什么可能是值得的。

    关键是 C++ 中的 函数 是具有名称和可能的函数参数的东西,并使用以下语法调用:

    func(arg1,arg2,...)
    

    换句话说,首先是名称,然后是圆括号,然后是逗号分隔的参数列表。这是C++的函数调用语法。

    operator 以标准第 5 条所述的方式使用。语法的细节取决于运算符的种类,例如有& 等一元运算符,+* 等二元运算符;还有三元条件运算符? :,然后是newdeletesizeof等特殊关键字,其中一些翻译为用户定义类型的函数调用,但他们不使用上述函数调用语法。 IE。你不打电话

    new(arg1,arg2,...)
    

    但是,您使用了一种特殊的“一元表达式语法”(第 5.3 节),除其他外,这意味着关键字new 之后没有圆括号(至少,不是必须)。

    作者在您引用的部分中谈到的正是这种句法差异。

    【讨论】:

      【解决方案3】:

      “运算符和函数有什么区别?” 句法。但实际上,这纯粹是关于 语言:在 C++ 中,+ 是一个中缀运算符(并且仅 运算符可以是中缀),func() 将是一个函数。但 即使这并不总是正确的:MyClass::operator+() 是 一个函数,但它可以并且通常使用 运算符语法。

      其他语言有不同的规则:在像 Lisp 这样的语言中, 没有真正的区别。可以区分 内置函数与用户定义函数,但 区分有些人为,因为您可以轻松地 扩展 lisp 以添加其他内置函数。并且有 允许对用户定义使用中缀表示法的语言 职能。像 Python 这样的语言在它们之间映射:lhs + rhs 映射到函数调用 lhs.__add__( rhs )(所以 “运算符”实际上只是语法糖)。

      总之,编程语言一般没有规则。 只有两个不同的词,每种语言都是 随意使用它们,以最好地描述语言。

      【讨论】:

        【解决方案4】:

        那么,一般编程语言中运算符与函数的确切区别是什么?

        范围很广。在抽象语法树中,运算符是一元、二元或有时是三元节点 - 将表达式与特定优先级绑定在一起,例如+ 的优先级低于*,而* 的优先级又低于new

        函数是一个更抽象的概念。作为原语,它们是类型化的子例程入口点,根据语言可以用作具有词法范围的右值。

        C++ 允许通过将运算符评估动态分派给所述方法来使用方法覆盖(重载)运算符。这是一种语言“功能”——正如这个问题的存在所暗示的那样——主要是让人们感到困惑,并且在 Go 中不可用。

        【讨论】:

          【解决方案5】:

          运算符是 c++ 语言语法的一部分,在 C++ 中,如果您不想要默认行为,您可以将它们“重载”为函数,对于复杂类型或用户定义类型,语言可能没有已知运算符的语义,所以 yuser可以用自己的实现重载它们。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-04-07
            • 2019-07-19
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多