неправильно выбранная функция - PullRequest
26 голосов
/ 02 декабря 2011

Я пытался очистить некоторый код, который использует char* с std::string, и столкнулся с проблемой, которая иллюстрируется следующим кодом.

void Foo( int xIn , const std::string & fooIn )
{
    std::cout << "string argument version called \n";
}

void Foo( int xIn ,  bool flagIn = true )
{
    std::cout << "bool argument version called \n";
}

int main()
{
    int x = 1;
    Foo( x , "testing" );
    return 0;
}

Когда я запускаю программу, я получаю версия аргумента bool с именем .Является ли преобразование char* в bool более предпочтительным, чем char* в const std::string&, или Visual Studio 2008 подшучивает?

Ответы [ 3 ]

27 голосов
/ 02 декабря 2011

Как это ни удивительно, компилятор совместим: преобразование char* в bool предпочтительнее преобразования в std::string.

Подробнее здесь .

Точные правила изложены в стандарте C ++. Они удивительно сложны, но здесь важен следующий параграф:

C ++ 11 13.3.3.2 Ранжирование последовательностей неявного преобразования [over.ics.rank]

2 При сравнении основных форм последовательностей неявного преобразования (как определено в 13.3.3.1) - стандартная последовательность преобразования (13.3.3.1.1) лучшая последовательность преобразования, чем определенная пользователем последовательность преобразования или последовательность преобразования многоточия

char* -to- bool требует "стандартной последовательности преобразования", тогда как char* -to- string требует "определенной пользователем последовательности преобразования". Поэтому первое предпочтительнее.

9 голосов
/ 02 декабря 2011

Они оба являются потенциальным совпадением, но компилятор предпочитает версию bool, поскольку для соответствия версии string требуется предоставляемая пользователем (или, в данном случае, предоставляемая библиотекой) функция преобразования.

Если вы действительно хотите это сделать, перегрузка для const char* может привести вас туда:

void Foo( int xIn, const char* in)
{
    return Foo( xIn, string(in) );
}

Я бы предположил, что при этом очень хороший шанскомпилятор выполнит на нем немало оптимизаций.

1 голос
/ 02 декабря 2011

Одним из простых исправлений было бы изменение bool на int - существует неявное преобразование из указателя в bool, но не в int. bool до int не является проблемой, поэтому существующий код, который передает bools, продолжит работать.

К сожалению, это немного влияет на читабельность кода, маскируя намерение параметра.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...