Search code examples
c++templatesfriend

C++ template class friend with all type


I have a Vector class and I overload the operator*

I would like to be able to multiply a Vector of float with a Vector of int.

I have the following code but when I compile him, I have an error because I don't have access to private fields.

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;
}

I also tried this but I can access to private fields of v1 but not to the private fields of 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;
    }
}

Solution

  • Your first version declares one specialization of Vecteur a friend of another. This doesn't help your operator *, since this is still not a friend and can't access private members.

    Add proper friend declaration for template overload in your Vecteur (and you do not need to friend the specialization):

    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
    

    Alternatively, you can friend the specialization, and add operator* as a member, but I do not like this, since such overloaded operators are more cleanly implemented as freestanding functions.