模板类的模板友元函数

Template friend function of template class

本文关键字:函数 友元      更新时间:2023-10-16

如果函数的模板参数包括但不限于类的模板参数,我想知道如何使函数成为类的朋友并在类外定义函数。

例如,我有以下模板类和模板友元函数:

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

这是一个函数模板,采用两个模板参数:TN

但是,在您的类中,您可以创建一个具有以下签名的函数模板作为好友:

template<typename T>
friend Matrix<N> operator* (const Matrix<N> &m1, const T &m2);

这只有一个模板参数:TN在这里已修复。此友元声明还声明此函数模板。这是一个更好的匹配,但实际上没有定义,因此你会看到行为。


我认为你有两个选择。

  1. 删除operator*的命名空间范围声明,只需在Matrix的定义中声明和定义友元operator*

  2. 更改友元声明以匹配命名空间范围的声明:

    template<typename T, int M>
    friend Matrix<M> operator* (const Matrix<M> &m1, const T &m2);
    

(1( 通常是更好的选择 - 不涉及在全局范围内添加更多operator*,这对编译时间有好处。