p1
и p2
указывают на одно и то же содержимое строки, следующие коды сравнивают их адреса, которые различны.
const char *p1 = "abc";
const char p2[] = {'a', 'b', 'c', '\0'};
cout << (p1 == p2) << endl; // 0 (false)
Но когда я строю строковую переменную на основе p2
, то сравнение p1
и строковой переменной дает 1
вместо 0
.
string s1(p2);
cout << (p1 == s1) << endl; // 1 (true)
Мой вопрос: строковый класс имеет конструктор, который принимает const char*
качестве единственного аргумента, который сообщает компилятору, когда возможно, преобразовать const char*
в строку:
string (const char* s);
Почему компилятор не преобразовывает p2
во временную строковую переменную, а затем сравнивает его с p1
с помощью оператора, определенного в классе строк:
bool operator== (const char* lhs, const string& rhs);
Это потому, что c++ может сравнивать две константы const char*
переменные p1
и p2
(другими словами, p1==p2
является допустимым c++ оператором без преобразования строки), а семантика - независимо от того, являются ли они одним и тем же физическим адресом или нет (в вашем примере это не так, и поэтому возвращается false
).
Компилятор не вызывает эту перегрузку operator==
потому что она не может - перегрузка разрешения для операторов только срабатывает, если хотя бы один из типов в выражении имеет класс или тип перечисления.
Из С++ 11 проект n3290 §13.3.1.2 Операторные выражения:
Если ни один из операндов оператора в выражении не имеет тип, который является классом или перечислением, оператор считается встроенным оператором и интерпретируется в соответствии с пунктом 5.
(И пункт 5 определяет ==
в разделе §5.10, с обычной семантикой сравнения указателей между прочим.)
Так что перегрузка даже не рассматривается. Вы просто не можете перегружать операторов только встроенными типами.