gcc — C ++ выбирает «неправильный» перегруженный метод с параметрами по умолчанию

У меня есть следующий интерфейс

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.

1

Решение

Вы поражаете тот факт, что указатели могут быть неявно преобразованы в 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)); }

Живой пример

4

Другие решения

Компилятор предпочитает преобразование из const char* в bool за преобразование в UDT (std::string). Если нужно, просто добавьте больше перегрузок для const char* также.

4

Разрешение перегрузки имеет несколько шагов: во-первых, набор жизнеспособный функции выбраны. Эти жизнеспособные функции должны иметь достаточно параметров для вызова, учитывая многоточие и / или аргументы по умолчанию. Кроме того, каждый аргумент должен быть преобразован в соответствующий тип параметра. За 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); предпочтительнее альтернативы.

1
По вопросам рекламы [email protected]