Ambiguous Call of "long unsigned int" for "uint32_t"
c++
Solution
The following is my "test" based on the code provided above:
#include <string>
#include <cstdint>
#include <iostream>
std::string f( uint8_t) { return "ui8";}
std::string f( int8_t) { return "i8";}
std::string f(uint16_t) { return "ui16";}
std::string f( int16_t) { return "i16";}
std::string f(uint32_t) { return "ui32";}
std::string f(unsigned long long int) { return "unsigned long long";}
std::string f(unsigned long int) { return "unsigned long";}
std::string f( int32_t) { return "i32";}
//std::string f(uint64_t) { return "ui64";}
std::string f( int64_t) { return "i64";}
int main()
{
unsigned long x = 42;
unsigned y = 17;
uint32_t z = 9;
uint64_t w = 135;
std::cout << "x: "<< f(x) << " y: " << f(y) << " z: " << f(z) << " w: " << f(w) << std::endl;
}
Sample output:
$ clang++ ambig.cpp -std=c++0x -Wall -m64
$ ./a.out
x: unsigned long y: ui32 z: ui32 w: unsigned long
$ clang++ ambig.cpp -std=c++0x -Wall -m32
$ ./a.out
x: unsigned long y: ui32 z: ui32 w: unsigned long long
(I copied my run with clang++, but the results are the same for g++)
This makes sure that both the `unsigned long` and `unsigned long long` types are covered. Unfortunately, one of those is `uint64_t`, so it has to be removed.
If you do declare variables as `unsigned long`, you must supply a function that takes exactly that - and relying on it being equivalent to `uint32_t` is probably incorrect - even if they are the same bitsize.
Problem
I have a bunch of functions overloaded for all of the `[u]int{8|16|32|64}_t` types: ``` std::string f( uint8_t) { /*something*/ } std::string f( int8_t) { /*something*/ } std::string f(uint16_t) { /*something*/ } std::string f( int16_t) { /*something*/ } std::string f(uint32_t) { /*something*/ } std::string f( int32_t) { /*something*/ } std::string f(uint64_t) { /*something*/ } std::string f( int64_t) { /*something*/ } //A few more overloads with a few more types (bool, float, const char*, etc.) ``` I now call the function name with an argument of type `long unsigned int`: ``` template <typename type_blah> class Something { public: //... std::string call_f(void) const { return f(*((type_blah*)(internal_variable))); } //... }; ``` This produces an error: error: call of overloaded 'f(long unsigned int&)' is ambiguous This happens, I suppose, because `unsigned int` and `uint32_t` are different types. But, I can't overload the function more for `long unsigned int` because this is a redundant definition. I.e.: ``` std::string f(long unsigned int) { /*something*/ } ``` . . . produces: error: 'std::string f(uint32_t)' previously defined here It seems the type mechanisms are working against each other: it can't figure out which conversion to use because each conversion is equally valid, but a no-conversion overload can't be defined because it already has been. I can't cast the argument for various reasons. Is there a way out of this? Platform is g++ MinGW x86 running on Windows 7 x86-64.