Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在模板化类之外定义非模板函数_C++_Templates_Friend Function_Template Classes - Fatal编程技术网

C++ 在模板化类之外定义非模板函数

C++ 在模板化类之外定义非模板函数,c++,templates,friend-function,template-classes,C++,Templates,Friend Function,Template Classes,我正在学习非模板友元函数&模板友元函数到模板化类。所以我尝试了下面的代码: #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); };

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

#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;
}
但是我想知道,在类定义之外定义friend fuinction有什么技巧吗


谢谢。

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

可以通过向前声明类和函数来实现这一点

#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;
}
#包括
模板
cl类;
模板
无效非模板朋友(cl m);
模板
类别cl
{
私人:
T值;
公众:
cl()=默认值;
显式cl(tv):val(std::move(v)){
friend void non_template_friend(cl m);//现在我们可以在这里参考模板的特定安装
};
模板
在第一个程序中无效非模板朋友(clm){std::cout

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

这是一个模板类,一个非模板的朋友函数声明实际上声明了一组重载的非模板函数。< /P>没有问题。它有点丑,但是它完成了任务。C++没有更清晰的方法。我有一个问题:在C++的见解中:生成的代码显示了相同的专业朋友FUNC的两个定义。我不知道为什么,但我知道编译器可以有多个相同模板的定义。通常每个使用它的TU都有一个。链接器会丢弃所有的定义,只有一个,并假设它们是相同的(如果不是,那就是UB)。与

内联
模板无效非模板朋友(..)发生的情况相同
.name现在似乎错了……因此,如果我理解了这个概念,如果我想将一个非模板函数交给一个模板类,我必须1)在类内编写定义,或2)在类内声明它并强制定义它的所有专用版本。@Blood HaZaRd没有必要为所有专用类声明非模板函数类的非模板化。仅声明将在程序中使用的非模板友元函数就足够了。如果要在类中定义非模板友元函数,则只有一个定义相同,即无法“专门化”非模板友元函数。是的,我的意思是:)仅适用于所使用的类型^^。@Blood HaZaRd您认为最好的答案并不是指非模板友元函数。在他的示例中,他声明了一个模板友元函数。它与非模板友元函数不同。@super例如,让我们假设我们有两个函数ns template void f(T)和void f(int);如果我们想为int类型的参数调用模板函数,我们必须至少写f(x);如果我们只写f(x);那么调用非模板函数。因此我们使用术语“模板函数”和“非模板函数”。对于这个调用f(x)我们说的是调用模板函数。与
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;}
#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