C ++访问具有不同模板参数值的模板化结构的受保护成员

时间:2018-05-28 01:35:06

标签: c++ templates operator-overloading friend protected

我正在创建模板化矩阵乘法函数,其中返回的矩阵与左侧矩阵的大小不同。在该函数中,我需要访问要返回的矩阵的受保护成员,但是我得到编译器错误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中的受保护变量?

2 个答案:

答案 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>不同。