2013-05-01 2 views
4

Вот тема на тему:Будет вызвана перегруженная функция C++?

#include <string> 
#include <iostream> 

void test(bool val) 
{ 
    std::cout << "bool" << std::endl; 
} 

void test(std::string val) 
{ 
    std::cout << "std::string" << std::endl; 
} 

int main(int argc, char *argv[]) 
{ 
    test("hello"); 
    return 0; 
} 

Выход программы bool. Почему выбран вариант bool?

+4

Задайте себе вопрос: что это за тип «привет» и что он может быть преобразован? –

+3

Duplicate: http://stackoverflow.com/a/8359260/1171191 – BoBTFish

+2

Это станет более распространенной проблемой. Адвокаты Modern C++ (включая меня) не учат char * strings сначала или даже вообще. Тем не менее, буквальные строки являются символами * и, очевидно, это становится неинтуитивным для новичков. Это настоящая проблема. –

ответ

14

Для того, чтобы вызвать перегрузку bool необходимо следующее преобразование:

const char[6] ---> const char* ---> bool 

Для того, чтобы вызвать перегрузку std::string требуется следующее преобразование:

const char[6] ---> const char* ---> std::string 

Это включает в себя определенное пользователем преобразование (с помощью конструктора преобразования от std::string). Любая последовательность преобразования без пользовательского преобразования предпочтительна в последовательности с пользовательским преобразованием.

При сравнении основных форм последовательностей преобразования неявных (как это определенно в 13.3.3.1):

  • стандартная последовательность преобразования (13.3.3.1.1) является лучшей последовательностью преобразования, чем гается определена последовательность преобразования или последовательность преобразования многоточия и
  • [...]

стандартная последовательность преобразования один с участием только стандартной совместной nversions. Пользовательская последовательность преобразований представляет собой единое пользовательское преобразование.

6

Это потому, что "hello" имеет тип const char[6], который распадается на const char*, который в свою очередь, может быть преобразован в bool с помощью другого стандартного преобразования. Таким образом, общее преобразование:

const char[6] -> bool 

Может быть выполнено только с помощью стандартных преобразований.

С другой стороны, превращением const char* к std::string потребует определенного пользователя преобразования (вызывающего конвертирующего конструктора std::string), а стандартных преобразований являются предпочтительнее определенным пользователем преобразования при выполнении разрешения перегрузки.

+2

Почему люди продолжают настаивать на том, чтобы пройти через 'void *' для преобразования в 'bool'? * Любой указатель * может быть преобразован в 'bool' * напрямую * (4.12 * Атрибут арифметики, неперечисленного перечисления, указателя или указателя на тип члена может быть преобразован в prvalue типа bool. Нулевое значение, значение нулевого указателя , или значение указателя нулевого элемента преобразуется в значение false, любое другое значение преобразуется в значение true. *) –

+0

@ DavidRodríguez-dribeas: Вы правы. Я забыл об этом, и это не первый раз. Спасибо, что указали, я отредактировал ответ. –

Смежные вопросы