运算符需要零个或一个参数

Operator needs zero or one argument

本文关键字:一个 参数 零个 运算符      更新时间:2023-10-16

我有多个错误,说"<snippet of code> needs zero or one argument""<snippet of code> needs exactly one argument." 为了简单起见,我只会从我的file.h和我的 file.cc 中发布这些代码部分之一。我不相信我的 main.cc 有什么问题。此外,该函数必须是类my_intfriend函数,因此我不能使其成为不同类型的函数或仅使用访问器函数。任何人可以提供的任何帮助将不胜感激。谢谢!

file.cc

my_int类的友情功能):

my_int my_int::operator+(const my_int& num1, const my_int& num2) {
    my_int temp;
    temp = num1 + num2;
    return(temp);
}

文件.h

(在名为 my_int 的类内)

friend my_int operator+(const my_int& num1, const my_int& num2);
friend my_int operator+(const my_int& num1, const my_int& num2);

表示'声明一个接受 2 个参数的自由函数。让它成为朋友,这样它就可以看到我的私人成员

my_int my_int::operator+(const my_int& num1, const my_int& num2) {

表示 '定义(非法)成员函数运算符+,总共需要 3 个参数。

编辑:根据要求,添加更多信息。

有许多

"正确"的方法可以在类上实现运算符。"最佳实践"方法是将所有二元运算符实现为自由函数(运算符+作为自由函数声明为2个参数)。运算符 + 应尽可能以运算符 += 实现(一元运算符,因此在类中定义它)。这是最佳实践,因为它允许您编写将不同对象作为参数的运算符+重载。例如:

struct X {
  explicit X(int val) : _val (val) {}
  // getter
  int value() const { return _val; }
  // this helper += operator eases our journey later on
  X& operator+=(int delta) {
    _val += delta;
    return *this;
  }
  X& operator+=(const X& r) {
    _value += r.value();
    return *this;
  }
private:
  int _val;
}
// implements X + X
X operator+(X l, const X& r)
{
  return l += r;
}
// implements X + int
X operator+(X l, int r)
{
  return l += r;
}
// implement int + X (returns an X)
X operator+(int l, X r) {
  return r += l;
  return r;
}
// later, someone else defines a Y and wants it to be addable with X, returning a Z
struct Y {
  vector<int> get_numbers() const;
}
struct Z {
  Z(vector<int> v);
}
// implement Z = X + Y;
Z operator+(const X& l, const Y& r) {
  auto v = r.get_numbers(); // vector<int> instead of auto for c++03
  v.push_back(l.value());
  return Z { std::move(v) }; // c++11
// return Z(v); // c++03
}
// also implement Z = Y + X
Z operator+(const Y&l , const X&r) {
  auto v = l.get_numbers();
  v.push_back(r.value());
  return Z { std::move(v) };
}

请注意,可以将二进制运算符的自由函数形式声明为友元:

struct X {
  // this is a free function - not a class memeber, but it can see X::_value
  friend X operator+(X, const X&);
private:
  int _value;
};
// implementation
X operator+(X l, const X& r) {
  l._value += r._value;
  return l;
}

但我认为这种风格不如编写以一元运算符(上图)实现的真正未绑定的自由二进制运算符可取。

也可以将二进制运算符实现为成员函数 - 在这种情况下,它们使用一个参数声明和定义(另一个参数隐含为 this):

struct X {
  X operator+(X r);
private:
  int _value;
};
X X::operator+(const X& r) {
  // l is implied as *this
  return X { _value + r._value };
}

但这是一个错误,因为虽然它允许 (X + int) 的重载,但它不允许重载 (int + X),为此无论如何你都需要一个免费函数。

此方法:

my_int my_int::operator+(const my_int& num1, const my_int& num2);

是一个成员函数。成员函数运算符隐式将 this 指向的对象(将是一个my_int对象)作为其左参数。这意味着重载的参数声明不能包含多个对象。将您的签名更改为:

my_int my_int::operator+(const my_int& num2);

现在以前num1的东西现在*this.

运算符+可用于两种表达式:

  • 一元"加"表达式:+a
  • 二进制"加号"表达式:a + b

运算符对于这两种表达式都是可重载的。每个重载必须是一元或二进制。如果重载是成员函数,则隐式实例参数提供第一个操作数。

因此,您有以下选择:

免费功能:

  • a可转换为T时,R operator+(T a)有资格获得+a
  • a可转换为Tb转换为U时,S operator+(T lhs, U rhs);有资格获得a + b

成员功能:

 struct Foo
 {
     R operator+();        // #1
     S operator+(T rhs);   // #2
 } x;
  • 过载 #1 符合+x条件。
  • b 可转换为 U 时,重载 #2 有资格x + b