неоднозначный вызов перегруженной функции - PullRequest
7 голосов
/ 21 февраля 2012

У меня есть две функции:

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

Теперь я хочу передать '0' в качестве size_t:

DoSomething(0);

Компилятор выдает ошибку: "неоднозначный вызов перегруженной функции"

Чтобы решить эту проблему, я могу использовать static_cast, например:

DoSomething(static_cast<size_t>(0));

Или просто:

DoSomething(size_t(0));

Один из них лучше другого?Есть ли другие способы решения этой проблемы?

Ответы [ 3 ]

6 голосов
/ 21 февраля 2012

Это неоднозначно, потому что 0 имеет тип int, а не size_t.Он может преобразовывать либо в size_t, либо в указатель, поэтому, если у вас перегружены оба, это неоднозначно.В общем, я бы порекомендовал, если у вас перегружены функции, и одна из них может принимать целочисленный тип, вы добавляете перегрузку для int, возможно, в соответствии с:

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

Интегральные литералы имеютвведите int по умолчанию (если они не слишком велики, чтобы поместиться в int), и, предоставляя точное совпадение, вы избежите двусмысленности.

1 голос
/ 21 февраля 2012
#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 );
}

Может показаться удивительным, что это работает, но это не просто неявное преобразование типов на работе.Кроме того, постоянная времени компиляции 0 целочисленного типа неявно преобразуется в нулевой указатель.Например, функция null() избегает этого, потому что результат не является постоянной времени компиляции.

1 голос
/ 21 февраля 2012

Причина неоднозначности: NULL имеет числовое значение 0.

Если вам нужно void DoSomething( const tchar* apsValue ) при передаче 0 в качестве параметра, nullptr будет полезно.Проверьте это Что такое nullptr?

...