Pergunta

So I have a templated vektor class

template<t>
class vektor
{
...
}

and I want to be able to write

vektor<int> x;
vektor<float> y;
...
y = x;

so I modify the class

template<t>
class vektor
{
    template<typename U>
    vektor<T>& operator=(const vektor<U> &r) {
    ....
    }
...
}

And I'd like this function to be friend with r; that is, I want to be able to access the private members of r. Since operator= is special I can't overload operator= as a non-member function and friend it as I might normally do and friend declarations of say

template<typename U> friend vektor<U>& operator=(const vektor<T> &r);

also return "must be a nonstatic member function"

Is there a way to confer friendship in this example?

Foi útil?

Solução

There are two quick solutions for this problem (both of them are not ideal).

Suppose that the class with very interesting name vektor looks like this (it is only an example which should illustrate the following code):

template<typename T>
class vektor
{
    T data;

public:

    vektor(T otherData) :
        data(otherData)
    {
    }

    T GetData() const
    {
        return data;
    }

    // ...

};

Both of solutions can be tested on the following example of code:

vektor<int> x(1);
vektor<float> y(2.0f);

y = x;
std::cout << "x.data = " <<  x.GetData() << std::endl;
std::cout << "y.data = " <<  y.GetData() << std::endl;

First solution: auxiliary friend function template

In this solution an auxiliary friend function Copy is used to execute all copy operations and is called from copy assignment operator:

template<typename T>
class vektor
{
    // ...

public:

    // ...

    template<typename U>
    vektor<T>& operator=(const vektor<U>& r)
    {
        return Copy(*this, r);
    }

    template<typename V, typename U>
    friend vektor<V>& Copy(vektor<V>& l, const vektor<U>& r);

};

template<typename V, typename U>
vektor<V>& Copy(vektor<V>& l, const vektor<U>& r)
{
    l.data = static_cast<V>(r.data);

    return l;
}

Second solution: friend class template

Second solution is to make all vektor class template instantiations friends to each other:

template<typename T>
class vektor
{
    // ...

public:

    // ...

    template<typename U>
    vektor<T>& operator=(const vektor<U>& r)
    {
        data = static_cast<T>(r.data);

        return *this;
    }

    template<typename U>
    friend class vektor;

};
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top