Guess
Guess

Reputation: 145

Class object cannot access its own private member?

So basically I have this piece of class that's causing some big issues:

namespace container {
template<typename T, std::size_t size>
class Array
{
private:
    T m_array[size];

    /* Note: All elements must be of the same type, aka the type used to declare the Array object */
public:
    // Needed to create subarray 
    template<std::size_t previousSize>
    Array(const Array<T, previousSize>& other, int begin, int end)
    {
        assert(begin >= 0 && end < previousSize && "Index must be >= 0 or less than the previous array's size");

        std::size_t index{ 0 };
        do {
            m_array[index] = other.m_array[begin];
            ++begin;
            ++index;
        } while (index < size && begin <= end);

        while (index < size) {
            m_array[index] = T();
            ++index;
        }
    }

    template<std::same_as<T>...Args>
    explicit Array(const Args&... args)
        : m_array{static_cast<T>(args)... }
    {}

And in main(), I create two objects:

container::Array<int, 7> myarray{ 200, 500, 300, 499, 1, 10};
std::cout << myarray;
container::Array<int, 5> newArray{ myarray, 2, 4 };
std::cout << newArray;

Now the issue is that in this line:

m_array[index] = other.m_array[begin];

It looks like 'other' cannot access its m_array private member. The code works fine if I set m_array to public. If you could help me understand what the issue it, that'd be much appreciated.

Upvotes: 3

Views: 78

Answers (1)

463035818_is_not_an_ai
463035818_is_not_an_ai

Reputation: 122133

A simpler example for the same issue is this:

template <int x>
struct Foo {
    
    template <int y>
    void foo(const Foo<y>& other) {
        value = other.value;
    }

    private:
        int value = 0;
};

int main() {
    Foo<1> a;
    Foo<2> b;
    a.foo(b);  // ERROR ! cannot acces private member
}

Here Foo<1> and Foo<2> are two different types. Only an instance of Foo<1> has access to private members of Foo<1>.

You can make all instantiations friends of each other:

template <int x>
struct Foo {
    
    template <int y>
    void foo(const Foo<y>& other) {
        value = other.value;
    }

    template <int y> friend class Foo;

    private:
        int value = 0;
};

int main() {
    Foo<1> a;
    Foo<2> b;
    a.foo(b);  // OK !
}

The line template <int y> friend class Foo; makes every instantiation of Foo a friend of every other instantiation of Foo.

Upvotes: 3

Related Questions