Search code examples
c++templatesstackswapfriend

How to declare a friend function of a template inside a class and implement this friend function ouside class?


Well, I'm trying to implement the copy_and_swap idiom on my first Stack in C++, for that I need to create a swap function and this swap function needs to be a friend function, I tried to do it by this way:

template <class T>
class Stack {
    private:
        int top;
        T* a;
        int MAX;

    public:
        Stack(int MAX);
        Stack(Stack<T>& s);
        bool push(T x);
        bool pop();
        T peek();
        bool isEmpty();
        friend void swap(Stack<T>& f, Stack<T>& s);
        ~Stack();
};

template <class T>
void Stack<T>::swap(Stack<T>& f, Stack<T>& s){
//I will put something where yet.
}

But, the VSCode says this about the swap function: class model "Stack " does not have a "swap" member (I translate for English, my VSCode runs in Portuguese).

How I can do that without receiving this error?


Solution

  • Your friend function is not template, so to define outside, you would have to define the non template function for each type (which seems impracticable):

    void swap(Stack<int>& lhs, Stack<int>& rhs){/*..*/}
    void swap(Stack<char>& lhs, Stack<char>& rhs){/*..*/}
    void swap(Stack<MyType>& lhs, Stack<MyType>& rhs){/*..*/}
    

    Simpler (and better IMO) is to define inside the class.

    template <class T>
    class Stack {
    // ...
        friend void swap(Stack& lhs, Stack& rhs) { /*..*/ };
    };
    

    Alternative is to make the friend function template:

    template <class T> class Stack;
    template <class T> void swap(Stack<T>&, Stack<T>&);
    
    template <class T>
    class Stack {
    // ...
        friend void swap<>(Stack& f, Stack& s); // Only the specialization is friend
    };
    
    template <class T>
    void swap(Stack<T>& lhs, Stack<T>& rhs){ /**/ }