C++ 模板 class 所有类型的朋友
C++ template class friend with all type
我有一个 Vector class 并且我重载了运算符*
我希望能够将 float 向量与 int 向量相乘。
我有下面的代码,但是当我编译他的时候,我有一个错误,因为我没有访问私有字段。
template <class T>
class Vecteur
{
template <class U> friend class Vecteur;
private:
int m_dimensions;
T *m_values;
}
template<class T1, class T2>
T1 operator*(const Vecteur<T1> &v1, const Vecteur<T2> &v2)
{
assert(v1.m_dimensions == v2.m_dimensions);
T res = T();
for (int i = 0; i < v1.m_dimensions; i++)
{
res += v1.m_values[i] * v2.m_values[i];
}
return res;
}
我也试过了,但是我可以访问 v1 的私有字段,但不能访问 v2 的私有字段
template <class T>
class Vecteur
{
private:
int m_dimensions;
T *m_values;
template<class T2>
friend T operator*(const Vecteur<T> &v1, const Vecteur<T2> &v2)
{
assert(v1.m_dimensions == v2.m_dimensions);
T res = T();
for (int i = 0; i < v1.m_dimensions; i++)
{
res += v1.m_values[i] * v2.m_values[i];
}
return res;
}
}
您的第一个版本声明了 Vecteur
另一个朋友的一个专长。这对您的运营商没有帮助 *
,因为这仍然不是朋友,无法访问私人会员。
在您的 Vecteur
中为模板重载添加适当的友元声明(并且您不需要对专业化进行友元化):
template<class T>
class Vectuer {
//...
template<class T1, class T2> std::common_type_t<T1, T2>
friend operator*(const Vecteur<T1>& , const Vectuer<T2>& );
//...
};
// And than a definition after the declaration
或者,您可以将专业化添加为好友,并将 operator*
添加为成员,但我不喜欢这样,因为这样的重载运算符作为独立函数实现得更干净。
当您想要声明一个函数或 class 一个 class 的朋友时,花点时间看看您的设计并问问自己这是否绝对必要。
在发布代码的情况下,与其尝试解决与授予 friend
-ship 给 operator*
函数相关的问题,不如为 [=18] 的数据提供访问函数=] 并完全摆脱授予 friend
-ship 的需要。
template <class T>
class Vecteur
{
public:
int getDimensions() const { return m_dimensions; };
T& operator[](std::size_t i) { return m_values[i]; };
T const& operator[](std::size_t i) const { return m_values[i]; };
private:
int m_dimensions;
T *m_values;
};
// Does not require to be a friend of the class.
template<class T1, class T2>
typename std::common_type<T1, T2>::type operator*(const Vecteur<T1> &v1, const Vecteur<T2> &v2)
{
assert(v1.getDimensions() == v2.getDimensions());
typename std::common_type<T1, T2>::type res{};
for (int i = 0; i < v1.getDimensions(); i++)
{
res += v1[i] * v2[i];
}
return res;
}
我有一个 Vector class 并且我重载了运算符*
我希望能够将 float 向量与 int 向量相乘。
我有下面的代码,但是当我编译他的时候,我有一个错误,因为我没有访问私有字段。
template <class T>
class Vecteur
{
template <class U> friend class Vecteur;
private:
int m_dimensions;
T *m_values;
}
template<class T1, class T2>
T1 operator*(const Vecteur<T1> &v1, const Vecteur<T2> &v2)
{
assert(v1.m_dimensions == v2.m_dimensions);
T res = T();
for (int i = 0; i < v1.m_dimensions; i++)
{
res += v1.m_values[i] * v2.m_values[i];
}
return res;
}
我也试过了,但是我可以访问 v1 的私有字段,但不能访问 v2 的私有字段
template <class T>
class Vecteur
{
private:
int m_dimensions;
T *m_values;
template<class T2>
friend T operator*(const Vecteur<T> &v1, const Vecteur<T2> &v2)
{
assert(v1.m_dimensions == v2.m_dimensions);
T res = T();
for (int i = 0; i < v1.m_dimensions; i++)
{
res += v1.m_values[i] * v2.m_values[i];
}
return res;
}
}
您的第一个版本声明了 Vecteur
另一个朋友的一个专长。这对您的运营商没有帮助 *
,因为这仍然不是朋友,无法访问私人会员。
在您的 Vecteur
中为模板重载添加适当的友元声明(并且您不需要对专业化进行友元化):
template<class T>
class Vectuer {
//...
template<class T1, class T2> std::common_type_t<T1, T2>
friend operator*(const Vecteur<T1>& , const Vectuer<T2>& );
//...
};
// And than a definition after the declaration
或者,您可以将专业化添加为好友,并将 operator*
添加为成员,但我不喜欢这样,因为这样的重载运算符作为独立函数实现得更干净。
当您想要声明一个函数或 class 一个 class 的朋友时,花点时间看看您的设计并问问自己这是否绝对必要。
在发布代码的情况下,与其尝试解决与授予 friend
-ship 给 operator*
函数相关的问题,不如为 [=18] 的数据提供访问函数=] 并完全摆脱授予 friend
-ship 的需要。
template <class T>
class Vecteur
{
public:
int getDimensions() const { return m_dimensions; };
T& operator[](std::size_t i) { return m_values[i]; };
T const& operator[](std::size_t i) const { return m_values[i]; };
private:
int m_dimensions;
T *m_values;
};
// Does not require to be a friend of the class.
template<class T1, class T2>
typename std::common_type<T1, T2>::type operator*(const Vecteur<T1> &v1, const Vecteur<T2> &v2)
{
assert(v1.getDimensions() == v2.getDimensions());
typename std::common_type<T1, T2>::type res{};
for (int i = 0; i < v1.getDimensions(); i++)
{
res += v1[i] * v2[i];
}
return res;
}