我想知道如果函数的模板参数包括但不限于类的模板参数,如何使函数成为类的朋友并在类外定义函数。
例如,我有以下模板类和模板朋友函数:
template<int N> class Matrix;
template<typename T, int N> Matrix<N> operator*(const Matrix<N> &m1, const T &m2);
// class definition
template<int N>
class Matrix{
template<typename T>
friend Matrix<N> operator* (const Matrix<N> &m1, const T &m2);
};
// friend function definition
template<typename T, int N> Matrix<N> operator*(const Matrix<N> &m1, const T &m2)
{
return m1; // just as an example
}
如果我编译:
Matrix<3> m;
m * 1.0;
我会得到以下链接器错误:
test.cc:(.text+0x1c7): undefined reference to `Matrix<3> operator*<double>(Matrix<3> const&, double const&)'
collect2: error: ld returned 1 exit status
你的种类不匹配。
您最初的声明和后来的定义有这样的签名:
template<typename T, int N>
Matrix<N> operator*(const Matrix<N> &m1, const T &m2);
这是一个采用两个模板参数的函数模板:T
和 N
。
然而,在您的类中,您作为朋友创建了一个具有以下签名的函数模板:
template<typename T>
friend Matrix<N> operator* (const Matrix<N> &m1, const T &m2);
这只有一个模板参数:T
. N
在这里是固定的。此友元声明还声明此函数模板。这是一个更好的匹配,但实际上没有定义,因此你看到的行为。
我认为你有两个选择。
>
删除运算符*
的名称空间范围声明,只需在矩阵
”的定义中声明和定义友联的操作符*
。
更改友元声明以匹配命名空间范围声明:
template<typename T, int M>
friend Matrix<M> operator* (const Matrix<M> &m1, const T &m2);
(1) 通常是更好的选择-不需要在全局范围中添加更多的运算符*
,这有利于编译时间。
我有一个类模板和一个函数模板定义了一个,它引用要绑定到的模板类型。 我想要的是将< code>make_obj函数声明为< code>friend,这样它可以创建< code>Obj的,但是其他人不能(除了通过copy ctor)。 我尝试了几个朋友声明,包括 和 后者是使< code>make_obj的所有模板实例化成为< code>Obj类的朋友的不太理想的尝试。然而,在这两种情况下,我得到相
我正在学习一个视频教程,我想声明一个模板函数作为模板类的朋友。我不知道为什么代码会抛出错误。 编译器抛出错误。 错误: templates\u friends\u 38。cpp:在“void doSomething2(T)[T=int]”的实例化中:templates\u friends\u 38。cpp:40:19:此处需要templates\u friends\u 38。cpp:32:9:错误
是否允许在友元声明中为模板参数提供默认值? Visual Studio 2015似乎允许这样做。gcc拒绝了。我在cppreference页面上找不到任何内容。
我试图使乘法运算符成为名为TVector3的模板类的朋友。我读过,我可以在类声明中声明朋友函数之前,对其进行前向声明,但我这样做的尝试是徒劳的。我知道我可以简单地定义friend函数而不是声明它,但我希望它能与前向声明技术一起工作。 特别是,我试图为我的案例实施这个解决方案。我发现这篇文章也是David Rodriguez给出的解决方案(第三个版本),但我不知道我做错了什么。 我使用'g temp
考虑以下示例: 使用GCC 5.2编译会引发以下编译错误: 但是标准在14.6.5中说: 友元类或函数可以在类模板中声明。当模板被实例化时,其朋友的名称被视为在实例化点显式声明了专门化。 为什么编译失败?在GCC 3.4中,通过。
函数和整个类都可以声明为非模板类友元。使用类模板,可以声明各种各样的友元关系。友元可以在类模板与全局函数间、另一个类(可能是模板类)的成员函数间或整个类中(可能是模板类)建立。建立这种友元关系的符号可能很繁琐。 在下列X类的类模板中声明为: template<class T>class X 下列友元声明: friend void f1(); 使函数f1成为从上述类模板实例化的每个模板类的友元。 在