所有类型的C ++模板类朋友

问题描述 投票:-1回答:2

我有一个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;
    }
}
c++ templates friend
2个回答
1
投票

你的第一个版本宣布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*作为成员,但我不喜欢这样,因为这样的重载运算符更加干净地实现为独立函数。


0
投票

当你想要宣布一个函数或类是一个类的朋友时,请花点时间看看你的设计并问自己这是否绝对必要。

对于发布的代码,不是试图解决与向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;
}
© www.soinside.com 2019 - 2024. All rights reserved.