模板的模板友元函数class
Template friend function of template class
我想知道如果函数的模板参数包括但不限于 class,如何使函数成为 class 的友元并在 class 之外定义函数模板参数。
比如我有下面的模板class和模板友元函数:
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
.
但是,在您的 class 中,您将具有此签名的函数模板设为朋友:
template<typename T>
friend Matrix<N> operator* (const Matrix<N> &m1, const T &m2);
这只有一个个模板参数:T
。 N
固定在这里。这个友元声明也声明了这个函数模板。这是一个更好的匹配,但实际上并未定义,因此出现了您看到的行为。
我认为你有两个选择。
删除 operator*
的名称空间范围声明,仅在 Matrix
的定义中声明和定义友元 operator*
。
更改友元声明以匹配命名空间范围声明:
template<typename T, int M>
friend Matrix<M> operator* (const Matrix<M> &m1, const T &m2);
(1) 通常是更好的选择 - 不涉及将更多 operator*
添加到全局范围,这对编译时间有好处。
我想知道如果函数的模板参数包括但不限于 class,如何使函数成为 class 的友元并在 class 之外定义函数模板参数。
比如我有下面的模板class和模板友元函数:
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
.
但是,在您的 class 中,您将具有此签名的函数模板设为朋友:
template<typename T>
friend Matrix<N> operator* (const Matrix<N> &m1, const T &m2);
这只有一个个模板参数:T
。 N
固定在这里。这个友元声明也声明了这个函数模板。这是一个更好的匹配,但实际上并未定义,因此出现了您看到的行为。
我认为你有两个选择。
删除
operator*
的名称空间范围声明,仅在Matrix
的定义中声明和定义友元operator*
。更改友元声明以匹配命名空间范围声明:
template<typename T, int M> friend Matrix<M> operator* (const Matrix<M> &m1, const T &m2);
(1) 通常是更好的选择 - 不涉及将更多 operator*
添加到全局范围,这对编译时间有好处。