c++templatesprivatefriend

Is there a way to add a friend class that is itself but with different template arguments?


I was writing a numpy-equivalent variable-dimension array in C++. I used a template class to store different kinds of datatypes in the array.

Eventually, I had to write a code for the datatype converting. I would like to have the arrays to change their datatypes into another, so I wrote a constructor for the conversion. However, the class had to access the private values of the class but with different template arguments.

The following is a minimal example:

template <typename T>
class my_class
{
private:
    T value;
    
public:
    // Constructor to initialize the data
    my_class(T value) : value(value) {}

    // Constructor for the conversion
    template<typename O>
    my_class(my_class<O> another)
    {
        value = static_cast<T>(another.value);   // Cast the type to T
    }
};

However when I try to run the following test code:

int main()
{
    // Create an integer class
    my_class<int> a = 3;

    // Convert it to float
    my_class<float> b = a;

    return 0;
}

MSVC emits this error:

error C2248: 'my_class<int>::value': cannot access private member declared in class 'my_class<int>'

I tried adding a friend to the individual my_classes by following:

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

public:
    template <typename U>
    friend class my_class<U>;
    
    // ...
}

However this error occurred:

friend class my_class<U>;
             ^~~~~~~~~^
error C3772: 'my_class<U>': invalid friend template declaration

Is there a way to add a friend class that is itself but with different template arguments? Alternatively, if that's not possible, is there a way to access the private methods/values of a class itself but with different template arguments?

However, I would prefer the friend approach, as it allows me to just add the friend once and access the private methods/values later on.


Solution

  • You want this:

    template <typename U>
    friend class my_class;