У меня есть следующий интерфейс
virtual void send_command( const std::string& command, const std::string& key, const std::string& value, bool pipeline = true );
virtual void send_command( const std::string& command, const std::string& key, bool pipeline = true );
virtual void send_command( const std::string& command, bool pipeline = true );
это полностью реализовано в одном классе, который я потом назову следующим:
c.send_command("MUTLI");
c.send_command("SET", "foo", "bar");
c.send_command("GET", "foo");
c.send_command("EXEC");
Когда я проверяю, какая реализация метода вызывается, я вижу, что третий вызов (ПОЛУЧИТЬ ФУ) заканчивается, чтобы поразить последнюю реализацию:
virtual void send_command( const std::string& command, bool pipeline = true );
где «foo» неявно преобразуется в bool. То же самое относится к «SET», «foo», «bar» который попадает во вторую реализацию (string, string, bool)
Когда я делаю вызов с явным c-приведением к строке, как это
c.send_command("GET", (std::string)"foo");
Ожидаемый метод вызывается.
Я использую gcc (GCC) 4.7.2 20121109 (Red Hat 4.7.2-8) с C ++ 11.
Вы поражаете тот факт, что указатели могут быть неявно преобразованы в bool
(проверяя, что они не равны нулю), и что строковый литерал не является std::string
, но const char[]
который распадается в const char*
по вызову. Что вы можете сделать, это обеспечить дополнительную перегрузку, принимая const char*
:
void send_command(const std::string& command, const char* key)
{ send_command(command, std::string(key)); }
Компилятор предпочитает преобразование из const char*
в bool
за преобразование в UDT (std::string
). Если нужно, просто добавьте больше перегрузок для const char*
также.
Разрешение перегрузки имеет несколько шагов: во-первых, набор жизнеспособный функции выбраны. Эти жизнеспособные функции должны иметь достаточно параметров для вызова, учитывая многоточие и / или аргументы по умолчанию. Кроме того, каждый аргумент должен быть преобразован в соответствующий тип параметра. За c.send_command("GET", "foo");
у вас есть как жизнеспособные кандидаты
virtual void send_command( const std::string&, const std::string&, bool);
virtual void send_command( const std::string&, bool);
потому что третий параметр первого по умолчанию и строковые литеральные аргументы могут быть преобразованы в string const&
а также bool
,
После того, как жизненный набор установлен, компилятор просматривает необходимые преобразования аргументов. Преобразование не требуется, затем встроенные преобразования, а затем определенные пользователем преобразования. В этом случае преобразование для первого аргумента одинаково для обеих жизнеспособных функций. Для второго аргумента, преобразование в bool
это Buitlin, в то время как преобразование в string const&
не является. Следовательно send_command( const std::string&, bool);
предпочтительнее альтернативы.