Ambiguous call of an overloaded function

I have two functions:

void DoSomething( const tchar* apsValue ) void DoSomething( size_t aiValue ) 

Now I want to pass '0' as size_t:

 DoSomething(0); 

The compiler throws an error: "ambiguous call of an overloaded function"

To solve this problem, I can use static_cast, for example:

 DoSomething(static_cast<size_t>(0)); 

Or simply:

 DoSomething(size_t(0)); 

Is one of them better than the other? Are there any other solutions to this problem?

+4
source share
3 answers

This is ambiguous because 0 is of type int , not size_t . It can convert either size_t or a pointer, so if you have an overload of both, this is ambiguous. In general, I would recommend that if you have overloaded functions, and one of them can take an integral type, you add an overload for int , perhaps line by line:

 inline void DoSomething( int aiValue ) { DoSomething( static_cast<size_t>( aiValue ) ); } 

Integral literals are of type int by default (unless they are too large to fit into int ), and by providing an exact match, you avoid any ambiguity.

+4
source

Reason for ambiguity: NULL has a numeric value of 0 .

If you want void DoSomething( const tchar* apsValue ) when passing 0 as a parameter, nullptr will be useful. Check What is nullptr?

+1
source
 #include <iostream> #include <stddef.h> using namespace std; void DoSomething( char const* apsValue ) { cout << "ptr" << endl; } void DoSomething( size_t aiValue ) { cout << "int" << endl;} template< class Type > Type runtime_value( Type v ) { return v; } int null() { return 0; } template< class Type > Type* nullPointerValue() { return 0; } int main() { // Calling the integer argument overload: int dummy = 0; DoSomething( size_t() ); DoSomething( runtime_value( 0 ) ); DoSomething( null( ) ); DoSomething( dummy ); static_cast< void(*)( size_t ) >( DoSomething )( 0 ); // Calling the pointer argument overload: DoSomething( nullptr ); DoSomething( nullPointerValue<char>() ); static_cast< void(*)( char const* ) >( DoSomething )( 0 ); } 

It may seem surprising that this works, but it’s not just an implicit type conversion at work. This also means that the compile-time constant 0 of the integral type is implicitly converted to nullpointer. For example, the null() function avoids this, since the result is not a compile-time constant.

+1
source

Source: https://habr.com/ru/post/1397597/


All Articles