Ambiguous operator [](...) overload errors when compiling for SAM Due

How can I get rid of these infernal errors when compiling my code for a Due?

It does not seem to matter what integer types I use for the parameters of operator functions.

This compile error just keep on being generated!

Common.cpp: In function 'const char* fromChar(char)':

Common.cpp:77:13: error: ambiguous overload for 'operator[]' (operand types are 'CBuff<16ul>' and 'int')

   buffCommon[0] = cCh;

             ^

Common.cpp:77:13: note: candidates are:

Common.cpp:77:13: note: operator[](char*, int) <built-in>

In file included from Common.h:6:0,

                 from Common.cpp:3:

CString.h:24:11: note: char& CBuffBase::operator[](uint32_t)

     char& operator[](const uint32_t nI)

           ^

CString.h:28:11: note: char& CBuffBase::operator[](int32_t)

     char& operator[](const int32_t nI)

           ^

CString.h:32:11: note: char& CBuffBase::operator[](uint16_t)

     char& operator[](const uint16_t nI)

           ^

CString.h:36:11: note: char& CBuffBase::operator[](int16_t)

     char& operator[](const int16_t nI)

           ^

Common.cpp: In function 'double toReal(const char*, uint8_t)':

Common.cpp:183:15: error: ambiguous overload for 'operator[]' (operand types are 'CString' and 'int')

  if (strNumber[0] == '-')

               ^

Common.cpp:183:15: note: candidates are:

Common.cpp:183:15: note: operator[](const char*, int) <built-in>

Common.cpp:183:15: note: operator[](char*, int) <built-in>

Common.cpp:183:15: note: operator[](uint8_t* {aka unsigned char*}, int) <built-in>

Common.cpp:183:15: note: operator[](const uint8_t* {aka const unsigned char*}, int) <built-in>

In file included from Common.h:6:0,

                 from Common.cpp:3:

CString.h:166:18: note: char& CString::operator[](int32_t)

     inline char& operator [](const int32_t nI)

                  ^

CString.h:171:18: note: char& CString::operator[](uint32_t)

     inline char& operator [](const uint32_t nI)

                  ^

CString.h:176:18: note: char& CString::operator[](int16_t)

     inline char& operator [](const int16_t nI)

                  ^

CString.h:181:18: note: char& CString::operator[](uint16_t)

     inline char& operator [](const uint16_t nI)

                  ^

Common.cpp:186:12: error: ambiguous overload for 'operator[]' (operand types are 'CString' and 'int')

   strNumber[0] = '0';

            ^

Common.cpp:186:12: note: candidates are:

Common.cpp:186:12: note: operator[](const char*, int) <built-in>

Common.cpp:186:12: note: operator[](char*, int) <built-in>

Common.cpp:186:12: note: operator[](uint8_t* {aka unsigned char*}, int) <built-in>

Common.cpp:186:12: note: operator[](const uint8_t* {aka const unsigned char*}, int) <built-in>

In file included from Common.h:6:0,

                 from Common.cpp:3:

CString.h:166:18: note: char& CString::operator[](int32_t)

     inline char& operator [](const int32_t nI)

                  ^

CString.h:171:18: note: char& CString::operator[](uint32_t)

     inline char& operator [](const uint32_t nI)

                  ^

CString.h:176:18: note: char& CString::operator[](int16_t)

     inline char& operator [](const int16_t nI)

                  ^

CString.h:181:18: note: char& CString::operator[](uint16_t)

     inline char& operator [](const uint16_t nI)

                  ^

Common.cpp:196:17: error: ambiguous overload for 'operator[]' (operand types are 'CString' and 'int8_t {aka signed char}')

    if (strNumber[nI] == '.')

                 ^

Common.cpp:196:17: note: candidates are:

Common.cpp:196:17: note: operator[](const char*, int) <built-in>

Common.cpp:196:17: note: operator[](char*, int) <built-in>

Common.cpp:196:17: note: operator[](uint8_t* {aka unsigned char*}, int) <built-in>

Common.cpp:196:17: note: operator[](const uint8_t* {aka const unsigned char*}, int) <built-in>

In file included from Common.h:6:0,

                 from Common.cpp:3:

CString.h:166:18: note: char& CString::operator[](int32_t)

     inline char& operator [](const int32_t nI)

                  ^

CString.h:171:18: note: char& CString::operator[](uint32_t)

     inline char& operator [](const uint32_t nI)

                  ^

CString.h:176:18: note: char& CString::operator[](int16_t)

     inline char& operator [](const int16_t nI)

                  ^

CString.h:181:18: note: char& CString::operator[](uint16_t)

     inline char& operator [](const uint16_t nI)

                  ^

Common.cpp:198:23: error: ambiguous overload for 'operator[]' (operand types are 'CString' and 'int8_t {aka signed char}')

    else if ((strNumber[nI] == 'e') || (strNumber[nI] == 'E'))

                       ^

Common.cpp (6.28 KB)

Common.h (2.5 KB)

CString.cpp (20.9 KB)

CString.h (10.2 KB)

I think the reason is that the compiler can't find an exact match for your operator with the given types.
It has two options: it could convert the first argument (CBuff<16>) to a char *, or it could convert the second argument (int) to int32_t or any of the other integer types you defined the operator for.

Two things you could try: make an overload "operator", or make the char * conversion explicit: "explicit operator char *()".

Pieter

PieterP:
I think the reason is that the compiler can't find an exact match for your operator with the given types.
It has two options: it could convert the first argument (CBuff<16>) to a char *, or it could convert the second argument (int) to int32_t or any of the other integer types you defined the operator for.

Two things you could try: make an overload "operator", or make the char * conversion explicit: "explicit operator char *()".

Pieter

But I don't get why this is an issue for Due and not for any of the other boards.

It turns out that adding a version of the function that takes 'int' and 'unsigned int' as parameters fixes the error for Due.

But then cause the same compile error to be generated when compiling for uno or mega.

I don't know.
I had a similar problem between ARMv7 using GCC 4.8.5 and x86 using GCC 9, "int" and "int32_t" were distinct types on ARM, but the same type on x86.
Eventually, I gave up trying to figure out why, and I just added an ifdef around it:

#ifdef __arm__
// int version
#else
// int32_t version
#endif

Not sure what would be the solution in your case though, what's the error you get when you compile the int/unsigned int version for AVR?