c++templatesfriend-functiontemplate-classes

define non-template function outside a templated class


I was learning about non-template friend function & template friend function to a templated class. So I tried the code below :

#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;
}

so when I compile I got : undefined reference tonon_template_friend(cl)' ` So to resolve that I have to move the friend function definition inside the class definition like so :

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;}
};

But I was wondering,is there any trick to do to be able to define the friend fuinction outside the class definition ?

Thank you.


Solution

  • In the first program

    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;}
    

    You declared a non-template friend funcrion but then you declared and defined a template function with the same name/

    A non-template friend function declaration means thatf you have to provide a set of overloaded non-template functions for specializations of the template class/

    Here is a demonstrative program.

    #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;
    }
    

    The program output is

    10
    20.2
    

    That is in a template class a non-template friend function declaration is in fact declares a set of overloaded non-template functions.