2
votes

I have a template base class, and a derived template class. The derived one has a an overloaded method with an argument that holds a reference to an object of the same type of the base class. If these weren't a template class, I would have made the derived class a friend of the base class so that I can access the base's protected members in this case, but how do I do this with templates?

template <typename T>
class base
{
    // If this wasn't a template class, I would have done this:
    // friend class derived;

public:
    base(T val)
        : val_(val)
    {
    }

    virtual void assign(const base<T>& other)
    {
        val_ = other.val_;
    }

protected:
    T val_;
};

template <typename T>
class derived : public base<T>
{
public:
    derived(T val)
        : base<T>(val)
    {
    }

    virtual void assign(const base<T>& other)
    {
        this->val_ = other.val_; // error: ‘int base<int>::val_’ is protected
    }
};

int main()
{
    derived<int> a(5);
    derived<int> b(6);
    b.assign(a);
    return 0;
}
1
Why not simply base<T>::assign(other);? Why is derived responsible for managing the state of base? Anyway, if you really want to use friend, you can: template <typename T> class derived; template <typename T> class base { friend class derived<T>; };Igor Tandetnik
Possible duplicate of this: stackoverflow.com/questions/4010281/…Colin Basnett
cmbasnett: It's not, actually I have read that particular question before I posted and tried what was suggested in there, but this case is different. I'm trying to access a protected member of another instance.Tom
Igor, thanks the forward declaration of the template class and declaring it as a friend seems to do the trick.Tom

1 Answers

0
votes

Why having virtual? In your example derived::assign() does the same as base::assign().

class base
{
    ...
    public:
    ...
    void assign(const base<T>& other)
    ...
}
derived<int> b(6);
b.assign(a); //calls base<int>::assign(..)

If derived should do some more work in assign(..), use base<T>::assign(other); as proposed by Igor Tandetnik. No need to use friend.