Search code examples
c++templatesfriendspecialization

c++ Friend function not recognised as friend with template specialisation


I am trying to declare a function as friend to a class template with a protected member. Below is a minimal example.

template<int N> class myClass{
public:
    friend void f(const myClass& c);
protected:
    int a;
};

If I now define the function as

template<int N> void f(const myClass<N>& c){
    std::cout << c.a;
};

Then it works.

However if I use template specialisation

template<int N> void f(const myClass<N>& c);
template<> void f<1>(const myClass<1>& c){
    std::cout << c.a;
};

It does not recognise f as a friend anymore and complains that a is a protected member.

Why is that happening? What am I doing wrong?


Solution

  • The problem is that the friend declaration friend void f(const myClass& c); is a nontemplate friend declaration. That is, you're actually befriending a nontemplae free function. This is exactly what the warning tells you:

     warning: friend declaration 'void f(const myClass<N>&)' declares a non-template function [-Wnon-template-friend]
       12 |     friend void f(const myClass& c);
    

    To solve this you need to add a separate parameter clause for the friend declaration as shown below:

    template<int N> class myClass{
    public:
        template<int M>        //added this parameter clause
        friend void f(const myClass<M>& c);
    protected:
        int a;
    };
    

    Working demo