0

Learning Expression templates.

In Wandevoode and Jossutis's book Templates, the complete guide, section 18.2.3 The Operators, they define an operator+ with two arguments but not as a friend method.

template <typename T, typename R1, typename R2>
Array<T,A_Add<T,R1,R2> >
operator+ (Array<T,R1> const& a, Array<T,R2> const& b) {
    return Array<T,A_Add<T,R1,R2> >
           (A_Add<T,R1,R2>(a.rep(),b.rep()));
}

I am a beginner and hence insecure about what I know about C++.

Shouldn't this operator+ be a friend?

I tried

class A{
public:
    explicit A(int x) : a(x){};

    A& operator+(const A& x, const A& y){
        A temp{x.a + y.a};
        return temp;
    };
private:
    int a;

};

I am getting a binary 'operator+' has too many parameters.

Kae
  • 279
  • 2
  • 10
  • 1
    It doesn't have to be if it doesn't access any non-public members. – Neil Kirk Oct 29 '14 at 23:59
  • 2
    If this function access private or protected data then it should probably be a friend. Otherwise it will do fine on its own. – David G Oct 29 '14 at 23:59
  • I see. I think I had got the idea that `A+B` would call `A.operator+(B)` when `operator+` is a member method or `operator+(A,B)` when it is a friend. So, it also makes sense `A.operator+(A,B)`. – Kae Oct 30 '14 at 00:51
  • @Karene: No, `A.operator+(A,B)` makes no sense. `A+B` can call `operator+(A,B)` if it's a non-member, whether or not it's a friend. Being a friend just gives it access to private members, which isn't needed here. – Mike Seymour Oct 30 '14 at 00:55
  • @MikeSeymour I keep getting a 'too many parameters' error. Using VisualC++ in Visual Studio, if that makes any difference. – Kae Oct 30 '14 at 01:09
  • The member function version of operator+ has only one argument. The object it is called on is the left hand side. – Retired Ninja Oct 30 '14 at 01:16
  • @RetiredNinja Yes, that is what I had read and that is the reason for my question. Shouldn't the operator in the book be a friend? .... OOOooooh!!!! I just realized. Maybe in the book the operator+ definition is not inside a class definition. Is that it? – Kae Oct 30 '14 at 01:23
  • Yes, that's it!!! Thanks to all of you. – Kae Oct 30 '14 at 01:24
  • Yes, the function in the book is not a member function. The reason you might make it a friend is if it needs access to non-public members or functions. – Retired Ninja Oct 30 '14 at 01:25

2 Answers2

1

Your "binary" operator + member function gives you the "too many parameters" error because it has three parameters: the x and y you specified, plus the implicit this parameter. This means it actually takes three arguments, which of course is impossible.

You can make a member function taking one explicit parameter and the implicit this, but in the opinion of many people, these binary operators such as add and subtract are better implemented outside the class, in the same namespace as the class, as free functions taking two explicit parameters. This works especially well if the data needed to fulfill the operation can be publicly accessed (otherwise you must use friend, which is OK if truly necessary).

John Zwinck
  • 239,568
  • 38
  • 324
  • 436
0

To summarize for the next reader.

There seem to be three forms of overloading binary arithmetic operators.

First: A member method taking one parameter by const reference. The const tothe return value is used (according to this reference) to avoid (x+y)=z.

class A{
  const A operator+(const A& other){
    // ... 
  };
};

Second: A friend method, and therefore included in the definition of the class, taking two parameters.

class A{
  friend A& operator+(const A& operand1, const A& operand2){
    // ... 
  };
};

Third: A non-member method taking two parameters.

class A{
  // ...
};

A operator+(const A& operand1, const A& operand2){
   // ...
};
Kae
  • 279
  • 2
  • 10