我正在创建模板化矩阵乘法函数,其中返回的矩阵与左侧矩阵的大小不同。在该函数中,我需要访问要返回的矩阵的受保护成员,但是我得到编译器错误C2248:无法访问受保护的成员。我相信这是因为模板参数的大小不同。
template<typename T, std::size_t r, std::size_t c>
struct Matrix
{
template<std::size_t c2>
Matrix<T, r, c2> operator*(const Matrix<T, c, c2>& rhs);
protected:
int test;
};
template<typename T, std::size_t r, std::size_t c>
template<std::size_t c2>
Matrix<T, r, c2> Matrix<T, r, c>::operator*(const Matrix<T, c, c2>& rhs)
{
Matrix<T, r, c2> retMat;
retMat.test;
return retMat;
}
我尝试了operator*()
乘法函数的推荐信息:
...
protected:
int test;
template<std::size_t c2>
friend Matrix<T, r, c> Matrix<T, r, c2>::operator*(const Matrix<T, c2, c>& rhs);
};
但我明白了:
error C2245: non-existent member function Matrix<T,r,c>::operator * specified as friend (member function signature does not match any overload)
如何使用不同大小的模板参数参数访问Matrix
中的受保护变量?
答案 0 :(得分:2)
无法访问受保护的成员。我相信这是因为模板参数的大小不同。
确切地说:Matrix<int, 2, 3>
是与(例如)Matrix<int, 3, 4>
不同的类型;因此,在Matrix<int, 2, 3>
方法中,您无法访问test
的{{1}}成员。
我尝试了
Matrix<int, 3, 4>
乘法函数
这是正确的方法,但你忘记了一个重要元素:operator*()
函数不是类的方法;这是一个正常的功能。
如果将friend
实现为类的方法(由于许多原因,错误的方式),它只需要一个显式参数(operator*()
右侧的操作数),因为另一个元素( *
)左侧的操作数隐含地是*
元素。
但是当你将*this
作为函数(operator*()
实现到类)时,没有隐式的friend
元素;所以该功能需要两个参数。
你错了
*this
因为只接收参数而不是template<std::size_t c2>
friend Matrix<T, r, c> Matrix<T, r, c2>::operator*(const Matrix<T, c2, c>& rhs);
。
解决此问题的正确方法(恕我直言)是一个函数(不是方法)如下
Matrix<T, r, c2>::
必须是template <typename T, std::size_t D1, std::size_t D2, std::size_t D3>
Matrix<T, D1, D3> operator* (Matrix<T, D1, D2> const & m1,
Matrix<T, D2, D3> const & m2)
{
Matrix<T, D1, D3> retMat;
retMat.test = m1.test + m2.test;
return retMat;
}
,Matrix<T, D1, D2>
和Matrix<T, D2, D3>
的朋友。
您可以尝试在类
中定义它Matrix<T, D1, D3>
但这是错误的,因为在不同的类中导致相同函数的多重定义。
所以我建议声明(但不要定义)类中的template <typename T, std::size_t R, std::size_t C>
struct Matrix
{
protected:
T test;
template <typename U, std::size_t D1, std::size_t D2, std::size_t D3>
friend Matrix<U, D1, D3> operator* (Matrix<U, D1, D2> const & m1,
Matrix<U, D2, D3> const & m2)
{
Matrix<T, D1, D3> retMat;
retMat.test = m1.test + m2.test;
return retMat;
}
};
operator*()
friend
和在外面定义。
以下是完整的工作示例
template <typename T, std::size_t R, std::size_t C>
struct Matrix
{
protected:
T test;
template <typename U, std::size_t D1, std::size_t D2, std::size_t D3>
friend Matrix<U, D1, D3> operator* (Matrix<U, D1, D2> const & m1,
Matrix<U, D2, D3> const & m2);
};
答案 1 :(得分:0)
它不是关于“大小”,而是关于不同类型的矩阵。
更改类模板的模板参数使该实例化与任何其他实例化不同,因此,无法访问另一个实例的私有/受保护成员。
另外,你不能使用朋友,因为你不知道(预先)第二个矩阵的列数。
IMO的方法是通过访问者公开会员。
祝你好运!<强>更新强>
看看这个函数签名:
Matrix<T, r, c2> Matrix<T, r, c>::operator*(const Matrix<T, c, c2>& rhs)
类型Matrix<T, c, c2>
与类型Matrix<T, r, c>
不同,并且它们都与返回的类型Matrix<T, r, c2>
不同。