具有不同模板参数值的模板结构的 C++ 访问受保护成员
C++ Access Protected Member of Templated Struct with Different Template Parameter Values
我正在创建一个模板化矩阵乘法函数,其中返回的矩阵与左侧矩阵的大小不同。在该函数中,我需要访问要返回的矩阵的受保护成员,但出现编译器错误 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
中的受保护变量?
这不是关于 "size",而是关于不同类型的矩阵。
更改 class 模板的模板参数会使该实例不同于任何其他实例,因此,一个实例无法访问另一个实例的 private/protected 成员。
此外,您不能使用 friend 因为您(事先)不知道第二个矩阵的列数。
要走的路,IMO,是通过访问器使成员 public。
祝你好运!
更新:
看看这个函数签名:
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>
不同。
cannot access protected member. I believe this occurs because the template arguments are different sizes.
确切地说:Matrix<int, 2, 3>
与(例如)Matrix<int, 3, 4>
是不同的类型;所以在 Matrix<int, 2, 3>
的方法中你不能访问 Matrix<int, 3, 4>
的 test
成员。
I tried friending the operator*()
multiplication function
这是正确的方法,但您忘记了一个重要因素:friend
函数不是 class 的方法;这是一个正常的功能。
如果将operator*()
实现为class的方法(由于多种原因错误的方法),它只需要一个显式参数(*
右边的操作数)因为另一个元素(*
左侧的操作数)隐含地是 *this
元素。
但是,当您将 operator*()
作为函数实现时(friend
到 class 或不),没有隐含的 *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>
的朋友。
您可能会想在 class
中定义它
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;
}
};
但这是错误的,因为会导致在不同的 classes 中对同一函数进行多次定义。
所以我建议在class
中声明(但不定义)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);
};
和在外面定义它。
以下是一个完整的工作示例
#include <type_traits>
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);
};
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;
}
int main ()
{
Matrix<long, 2U, 3U> a;
Matrix<long, 3U, 4U> b;
auto c { a * b };
static_assert( std::is_same<decltype(c), Matrix<long, 2U, 4U>>{}, "!" );
}
我正在创建一个模板化矩阵乘法函数,其中返回的矩阵与左侧矩阵的大小不同。在该函数中,我需要访问要返回的矩阵的受保护成员,但出现编译器错误 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
中的受保护变量?
这不是关于 "size",而是关于不同类型的矩阵。
更改 class 模板的模板参数会使该实例不同于任何其他实例,因此,一个实例无法访问另一个实例的 private/protected 成员。
此外,您不能使用 friend 因为您(事先)不知道第二个矩阵的列数。
要走的路,IMO,是通过访问器使成员 public。
祝你好运!
更新:
看看这个函数签名:
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>
不同。
cannot access protected member. I believe this occurs because the template arguments are different sizes.
确切地说:Matrix<int, 2, 3>
与(例如)Matrix<int, 3, 4>
是不同的类型;所以在 Matrix<int, 2, 3>
的方法中你不能访问 Matrix<int, 3, 4>
的 test
成员。
I tried friending the
operator*()
multiplication function
这是正确的方法,但您忘记了一个重要因素:friend
函数不是 class 的方法;这是一个正常的功能。
如果将operator*()
实现为class的方法(由于多种原因错误的方法),它只需要一个显式参数(*
右边的操作数)因为另一个元素(*
左侧的操作数)隐含地是 *this
元素。
但是,当您将 operator*()
作为函数实现时(friend
到 class 或不),没有隐含的 *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>
的朋友。
您可能会想在 class
中定义它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;
}
};
但这是错误的,因为会导致在不同的 classes 中对同一函数进行多次定义。
所以我建议在class
中声明(但不定义)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);
};
和在外面定义它。
以下是一个完整的工作示例
#include <type_traits>
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);
};
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;
}
int main ()
{
Matrix<long, 2U, 3U> a;
Matrix<long, 3U, 4U> b;
auto c { a * b };
static_assert( std::is_same<decltype(c), Matrix<long, 2U, 4U>>{}, "!" );
}