Pregunta

I have the following interface

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 );

that is fully implemented in one class which I will then call as the following:

c.send_command("MUTLI");
c.send_command("SET", "foo", "bar");
c.send_command("GET", "foo");
c.send_command("EXEC");

When I check which method implementation get's called, I see that the third call (GET foo) ends up to hit the last implementation:

virtual void send_command( const std::string& command, bool pipeline = true );

where "foo" is implicit converted to bool. The same counts for "SET", "foo", "bar" which hits the second implementation (string, string, bool) When I make the call with an explicit c-cast to a string like this

c.send_command("GET", (std::string)"foo");

The expected method gets called.

I am using gcc (GCC) 4.7.2 20121109 (Red Hat 4.7.2-8) with C++11.

¿Fue útil?

Solución

You're hitting the fact that pointers can implicitly be converted to bool (testing that they're not null), and that a string literal is not a std::string, but a const char[] which decays into a const char* on call. What you can do is provide an additional overload taking a const char*:

void send_command(const std::string& command, const char* key)
{ send_command(command, std::string(key)); }

Live example

Otros consejos

The compiler prefers the conversion from const char* to bool over a conversion to a UDT (std::string). If needed, just add more overloads for const char* as well.

Overload resolution has several steps: First, a set of viable functions is selected. These viable functions must have enough parameters for the call, considering ellipsis and/or default arguments. In addition, each argument has to be convertible to the corresponding parameter type. For c.send_command("GET", "foo"); you have as viable candidates

virtual void send_command( const std::string&, const std::string&, bool);
virtual void send_command( const std::string&, bool);

because the third parameter of the former is defaulted and the string literal arguments are convertible to string const& and bool.

After having the viable set, the compiler looks at the argument conversions needed. No conversion is prefered, then builtin conversions, then user defined conversions. In this case, the conversion for the first argument is the same in both viable functions. For the second argument, the conversion to bool is buitlin, while the conversion to string const& is not. Therefore send_command( const std::string&, bool); is prefered over the alternative.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top