Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ambiguous Call of "long unsigned int" for "uint32_t"

Tags:

c++

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.

like image 388
imallett Avatar asked Feb 23 '14 16:02

imallett


1 Answers

What platform are you using?

On Windows (Visual Studio 2010), unsigned long int is a distinct type from the others you mentioned.

Adding an overload specifically for that type resolved the error. This answer (and/or Google) may shed more light on the issue: Type of unsigned long is different from uint32_t and uint64_t on Windows (VS2010).

I defined an overload for unsigned long int like so:

std::string f( unsigned long int val )
{
  // Check that we chose the correct corresponding type
  // (This may vary by platform!)
  assert( sizeof( unsigned long int ) == sizeof( uint32_t ) );

  return f( static_cast<uint32_t>( val ) );
}

...tested in Visual Studio 2010 like so:

void main()
{
  std::cout << "sizeof( unsigned long int ): " << sizeof( unsigned long int ) << std::endl;
  std::cout << "sizeof( uint32_t ): "          << sizeof( uint32_t )          << std::endl;

  unsigned long int x = 1u;
  std::cout << f( x ) << std::endl;
}

...and got the expected result:

sizeof( unsigned long int ): 4
sizeof( uint32_t ): 4
uint32_t
like image 141
aldo Avatar answered Sep 21 '22 13:09

aldo