1

I know that in C++ functions can be overloaded by their const property, but I got an error when I run this piece of code:

#include <iostream>
#include <conio.h>

using namespace std;

template<class T> class Array
{
public:
    Array() : data(0), sz(0){}
    Array(unsigned size) : sz(size), data(new T[size]){}
    ~Array() 
    {
        delete[] data;
    }

    const T& operator[](unsigned n) const
    {
        if(n >= sz || data == 0)
        {
            throw "Array subscript out of range";
        }
        return data[n];
    }

    T& operator[](unsigned n)
    {
        if(n >= sz || data == 0)
        {
            throw "Array subscript out of range";
        }
        return data[n];
    }

    operator const T*() const
    {
        return data;
    }

    operator T*()
    {
        return data;
    }

private:
    T* data;
    unsigned sz;
    Array(const Array& a);
    Array& operator=(const Array&);
};

int main()
{
    Array<int> IntArray(20);

    for(int i = 0; i != 20; ++i)
    {
        IntArray[i] = i;
    }

    return 0;
}

The error comes from IntArray[i] = i; the complier says that it can't find the proper overload function. shouldn't it call T& operator[](unsigned n) ??

I'm using vs2010 as my complier

Thanks for any help.

Aman Aggarwal
  • 3,905
  • 4
  • 26
  • 38
shengy
  • 9,461
  • 4
  • 37
  • 61

2 Answers2

4

The call is ambiguous because the code requires a conversion (the index is int and your operator[] expects a value of type unsigned) and as the error message says, there a multiple possible conversions. (This would not be the case if you did not provide the operator T* conversion operator.)

error C2666: 'Array::operator []' : 4 overloads have similar conversions could be

  • 'int &Array::operator [](unsigned int)'
  • 'const int &Array::operator [](unsigned int) const'
  • 'built-in C++ operator[(const int *, int)'
  • 'built-in C++ operator[(int *, int)'

while trying to match the argument list '(Array, int)' with [T=int]

Just change your for loop to use an index of type unsigned so that it can select the proper overload.

for(unsigned i = 0; i != 20; ++i)
{
    IntArray[i] = i;
}

By the way, offering direct conversion to pointer types is usually considered a Bad Idea (TM) because it enables this syntax:

Array<int> array(20);
delete array;
André Caron
  • 44,541
  • 12
  • 67
  • 125
  • Alternatively, add overloads for `T& operator[](int n)` and the `const` variant so an `int` index doesn't need a conversion. It's a bit more code, but might make for a less frustrating experience using the class. – Michael Burr Feb 13 '12 at 03:02
  • 2
    @MichaelBurr: Indeed, but it would probably be a better choice to simple remove the "conversion to pointer" operators. `std::vector<>` doesn't provide an `operator[](int)` and does not produce this kind of problems. – André Caron Feb 13 '12 at 03:07
1

No, it should call T& operator[](int n).

This works:

for(unsigned int i = 0; i != 20; ++i)
{
    IntArray[i] = i;
}
Nemanja Boric
  • 21,627
  • 6
  • 67
  • 91