Подтвердить что ты не робот

Неправильно выбрана функция

Я пытался очистить код, который использует 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 играет на меня трюки?

4b9b3361

Ответ 1

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

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

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

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

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

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

Ответ 2

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

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

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

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

Ответ 3

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

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