0

I have this class:

template<typename T>
class array_eraser
{
    T* array;
    int size_array;
public:

    array_eraser(T &a[], int s)
    {
        size_array = s;
        array = new T[s];
        array = a;
    }
}

I call the class with this line in main:

std::string langs[] = { "C++", "Haskell", "Ada", "Python", "Ada" };
array_eraser<std::string> le(langs, sizeof(langs) / sizeof(langs[0]));

and I got this error: cannot convert argument 1 from 'std::string [5]' to 'T *[] What did i do wrong?

Jttaskk
  • 25
  • 4
  • 1
    `array = new T[s]; array = a;` Nice instant memory leak ;) allocating memory and immediately discarding it. – JHBonarius Dec 13 '20 at 21:13
  • Does this answer your question? [Passing an array by reference](https://stackoverflow.com/questions/5724171/passing-an-array-by-reference) – JHBonarius Dec 13 '20 at 21:16

1 Answers1

2

You are nicely demonstrating why not to use raw arrays.

  1. T &a[] is not a reference to an array of Ts but an array a of references to T. Maybe you wanted T (&a)[] - a reference to an array. But that will not fly either. Because in this case you disable the decay mechanics and you have to specify the size. This can be done using the template trick:
    template<std::size_t N>
    array_eraser(T (&a)[N]) {}
    
  2. If you really wanted T& a[], that is a no go, T a[] and T& a[] are never compatible.
  3. If you use array_eraser(T a[], int s), the array is not passed by value, but decays into a pointer. There is no difference between T a[] and T* a. Which brings me to your second mistake. array = a; will not copy arrays but only assign the pointers leaking the newly allocated array. You can copy the array using std::memcpy(array,a,s);.

So, unless you really have to and know what you are doing, use std::array or better std::vector if you need run-time and modifiable length. More typing with std:: stuff is not a good enough reason.

Quimby
  • 17,735
  • 4
  • 35
  • 55