C++ 友元函数不被识别为具有模板专业化的友元

mar*_*rco 3 c++ templates friend specialization

我试图将一个函数声明为具有受保护成员的类模板的友元。下面是一个最小的例子。

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

如果我现在将函数定义为

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

然后就可以了。

但是如果我使用模板专业化

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

它不再承认f自己是朋友,并抱怨说自己a是受保护的成员。

为什么会发生这种情况?我究竟做错了什么?

use*_*570 5

问题在于友元声明friend void f(const myClass& c);是非模板友元声明。也就是说,您实际上是在与非模板自由函数交朋友。这正是警告告诉您的内容:

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

为了解决这个问题,您需要为友元声明添加一个单独的参数子句,如下所示:

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

工作演示