我有一个Vector类,我重载了运算符*
我希望能够将Vector of float与Vector of 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*
作为成员,但我不喜欢这样,因为这样的重载运算符更加干净地实现为独立函数。
当你想要宣布一个函数或类是一个类的朋友时,请花点时间看看你的设计并问自己这是否绝对必要。
对于发布的代码,不是试图解决与向friend
函数授予operator*
-ship相关的问题,而是为类的数据提供访问器函数,并且不需要完全授予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;
}