Search code examples
c++operator-overloadingfriend

C++ overloading operator+ using a class and a int parameter as template


i can't figure out what's wrong on this code:

template <class T = char, int num = 100> class Stack;
template <class T = char, int num1 = 100, int num2 = 100> Stack<T, num1>& operator+=(Stack<T, num1>& s1, const Stack<T, num2>& s2);
template <class T, int num>
class Stack{
template <T, int num1, int num2 > friend  Stack<T, num1>& operator+=(Stack<T, num1>& s1, const Stack<T, num2>& s2);
public:
   ...
private:
   Entry* first;
   class Entry{
      ...
   }
   void append(const Stack& s){
        if(isEmpty()) first = &s;
        else first->last().next = &s;
   }
   ...
};
template <class T, int num1, int num2>
Stack<T, num1>& operator+=(Stack<T, num1>& s1, const Stack<T, num2>& s2){
    s1.append(Stack<T, num2>(s2));
    ...
};

The point is that i've already set the friendship from the class to the operator, and i'm still getting error: 'append' is a private member of 'Stack<char, 100>' so i'm doing something wrong on it, can someone please check this?


Solution

  • This

    template <T, int num1, int num2 > friend  Stack<T, num1>& operator+(Stack<T, num1>& s1, const Stack<T, num2>& s2);
    

    declares an operator+ function template that takes a value of type T, a value of type int, and another value of type int as template parameters as friend of your class template. Note how the function template you declared as friend is not the one you declared above the definition of Stack. The template argument lists are different. Above the definitionf of Stack, you declare:

    template <class T, int num1, int num2>
    //           ^ type parameter
    Stack<T, num1>& operator+(Stack<T, num1>& s1, const Stack<T, num2>& s2);
    

    but in the friend declaration you declare

    template <T, int num1, int num2>
    //        ^ non-type parameter
    Stack<T, num1>& operator+(Stack<T, num1>& s1, const Stack<T, num2>& s2);
    

    You'll have to write

    template <class U, int num1, int num2> friend Stack<U, num1>& operator+(Stack<U, num1>& s1, const Stack<U, num2>& s2);
    

    to make your original operator+ template a friend of the class template Stack

    Apart from all that, I would recommend that you stop right there and think about whether it really is a good idea that an expression like

    a + b
    

    implicitly modifies a. If you really must use an operator for this, an operator+= is probably a better way to express these semantics (personally, I'd probably just stick with an append function here). Since an operator+= must be a non-static member function, your initial problem then also disappears…