Неправильно выбрана функция
Я пытался очистить код, который использует 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 играет на меня трюки?
Ответы
Ответ 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, будет продолжать работать.
К сожалению, это немного влияет на читаемость кода, маскируя намерение параметра.