Ответ 1
Мое предположение заключается в том, что преобразование из указателя в bool является неявным преобразованием примитивного типа, где преобразование в std::string
требует вызова конструктора и создания временного.
Для использования следующих методов:
// Method 1
void add(const std::string& header, bool replace);
//Method 2
void add(const std::string& name, const std::string& value);
Похоже, что следующий код в конечном итоге вызовет метод 1 вместо метода 2:
something.add("Hello", "World");
Я закончил создание другого метода, который выглядит так:
//Method 3
void MyClass::add(const char* name, const char* value) {
add(std::string(name), std::string(value));
}
Это сработало. Таким образом, казалось бы, когда метод принимает "цитированную строку", он будет соответствовать в следующем порядке:
const char*
bool
std::string
Почему цитированная строка должна рассматриваться как bool
до std::string
? Это обычное поведение? Я написал достойный код для этого проекта и не имел никаких других проблем с выбранной сигнатурой метода...
Мое предположение заключается в том, что преобразование из указателя в bool является неявным преобразованием примитивного типа, где преобразование в std::string
требует вызова конструктора и создания временного.
В вашем случае у вас есть перегруженные функции. Разрешение перегрузки происходит в соответствии с разделом 13.3.
С++ 03 13.3.3.2/2:
При сравнении основных форм неявных последовательностей преобразования (как определено в 13.3.3.1)
- стандартная последовательность преобразования (13.3.3.1.1) является лучшей последовательностью преобразования, чем пользовательская последовательность преобразования или последовательность преобразования многоточия, и
- пользовательская последовательность преобразования (13.3.3.1.2) является лучшей последовательностью преобразования, чем последовательность преобразования многоточия (13.3.3.1.3).
Указатель преобразования в bool является стандартным преобразованием. Указатель преобразования в std::string - это определяемое пользователем преобразование.
4.12 Логические преобразованияЗначение r арифметики, перечисления, указателя или указателя на тип члена можно преобразовать в rvalue типа bool. Значение нуля, значение нулевого указателя или значение указателя нулевого элемента преобразуется в значение false; любое другое значение преобразуется в значение true.
Указатели имеют неявное преобразование в bool
. Возможно, вы видели следующее:
void myFunc(int* a)
{
if (a)
++(*a);
}
Теперь, в С++, неявные преобразования между встроенными типами имеют приоритет над преобразованиями между типами классов. Например, если у вас есть класс:
class Int
{
public:
Int(int i) {}
}
И вы перегрузили функцию для long
и Int
:
void test(long n) {cout << "long";}
void test(Int n) {cout << "Int";}
Вы увидите, что следующий код вызывает длительную перегрузку:
int i;
test(i);