0

I'm trying to write my own class which is supposed to represent a templated array. I wanted to define operator+ for it but in a way that it can add two arrays specified with different types(ofcourse if one can be promoted to the other and vice versa). In order to do that I had to make templated definition of the operator(is that good way at all?) and after compiling my compiler is reporting that, basically, as I've understood, can't find any of state members of my class. Code is down below any help appreciated... because code works perfectly fine when everything is public, but obviously that's not the point.

MyArray.hpp: In instantiation of ‘MyArray<decltype ((((MyArray<T>*)this)->MyArray<T>::ptr[0] + other[0]))> MyArray<T>::operator+(const MyArray<A>&) [with A = int; T = double; decltype ((((MyArray<T>*)this)->MyArray<T>::ptr[0] + other[0])) = double]’:
test3.cpp:65:3:   required from here
MyArray.hpp:94:32: error: ‘int* MyArray<int>::ptr’ is private within this context
       tmp[i] = ptr[i] + (other.ptr)[i];
                         ~~~~~~~^~~~
MojNiz.hpp:9:12: note: declared private here
   T* ptr = nullptr;



  #include <iostream>

    template <typename T>
    class MyArray {

      private:
   T* ptr = nullptr;
    size_t arraySize = 0;
    size_t maxCapacity = 0;

      public:
      template <typename A>
      auto operator+(const MyArray<A>& other)-> MyArray<decltype(ptr[0] + other[0])> {
        if (arraySize != other.size()) throw std::invalid_argument("Nope");
        MyArray<decltype(ptr[0] + other[0])> tmp;
        tmp.ptr = new decltype(ptr[0] + other[0])[arraySize];
        tmp.arraySize = arraySize;
        for (int i = 0; i < arraySize; ++i) {
          tmp[i] = ptr[i] + (other.ptr)[i];
        }
        return tmp;
      }
  • Please also paste your complete compiler error message. Also, `other[0]` implies an `operator[]` - is there one? – aschepler Jan 09 '20 at 00:30
  • @aschepler, thanks, I added compiler error message. Yeah, there is operator[] for my class and all of the others bells and whistles. Basically I'm trying to say that my code works perfectly if I declare state as public – Zlatan Radovanovic Jan 09 '20 at 00:37

1 Answers1

0

Remember that each MyArray specialization is its own independent class. A class always has access to its own members, but MyArray<int> and MyArray<long> have no access to each others' members!

I would make this operator+ a non-member friend. It's often difficult or even impossible to properly friend a member function, and there are also other benefits to making symmetric operators like binary + non-members. As long as all three classes involved friend the function template, it can use their members.

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

    template <typename A, typename B>
    friend auto operator+(const MyArray<A>& arr1, const MyArray<B>& arr2)
        -> MyArray<decltype(arr1[0] + arr2[0])>
    {
        // ...
    }
};
aschepler
  • 70,891
  • 9
  • 107
  • 161