在模板化 class 之外定义非模板函数

define non-template function outside a templated class

我正在学习非模板友元函数和模板友元函数到模板化 class。所以我尝试了下面的代码:

#include <iostream>   


template<typename T>
class  cl
{
private :
    T val;
public:
    cl()= default;
    explicit cl(T v) : val(std::move(v)) {}    

    friend void non_template_friend(cl m);
};

template <typename T>
void non_template_friend(cl<T> m)  { std::cout << m.val << std::endl;}


int main()
{

    cl<int> c(10);
    non_template_friend(c);
    return 0;
}

所以当我编译时我得到:undefined reference tonon_template_friend(cl)' `所以为了解决这个问题,我必须像这样在 class 定义中移动友元函数定义:

template<typename T>
class  cl
{
private :
    T val;
public:
    cl()= default;
    explicit cl(T v) : val(std::move(v)) {}    

    friend void non_template_friend(cl m) { std::cout << m.val << std::endl;}
};

但我想知道,是否有任何技巧可以在 class 定义之外定义朋友功能?

谢谢。

如果您想要 class 之外的定义,它需要是一个模板函数,因为它必须能够接受任何类型的 c1.

您可以通过前向声明 class 和函数来实现。

#include <iostream>

template<typename T>
class  cl;

template<typename T>
void non_template_friend(cl<T> m);

template<typename T>
class  cl
{
private :
    T val;
public:
    cl()= default;
    explicit cl(T v) : val(std::move(v)) {}    

    friend void non_template_friend<T>(cl m); //Now we can refer to a specific instatiation of the template  here
};

template <typename T>
void non_template_friend(cl<T> m)  { std::cout << m.val << std::endl;}


int main()
{

    cl<int> c(10);
    non_template_friend(c);
    return 0;
}

在第一个节目中

template<typename T>
class  cl
{
private :
    T val;
public:
    cl()= default;
    explicit cl(T v) : val(std::move(v)) {}    

    friend void non_template_friend(cl m);
};

template <typename T>
void non_template_friend(cl<T> m)  { std::cout << m.val << std::endl;}

您声明了一个非模板友元函数,但随后又声明并定义了一个具有相同名称的模板函数/

非模板友元函数声明意味着您必须为模板特化提供一组重载的非模板函数class/

这是一个演示程序。

#include <iostream>
template<typename T>
class  cl
{
private :
    T val;
public:
    cl()= default;
    explicit cl(T v) : val(std::move(v)) {}    

    friend void non_template_friend(cl m) ;
};

void non_template_friend( cl<int> m)  { std::cout << m.val << std::endl;}
void non_template_friend( cl<double> m)  { std::cout << m.val << std::endl;}

int main() 
{
    cl<int> c(10);
    non_template_friend(c);

    cl<double> c2( 20.2 );
    non_template_friend(c2);


    return 0;
}

程序输出为

10
20.2

也就是在一个模板中class一个非模板友元函数声明实际上是声明了一组重载的非模板函数