views:

204

answers:

3

Given the following methods:

// Method 1
void add(const std::string& header, bool replace);

//Method 2
void add(const std::string& name, const std::string& value);

It would appear that the following code will end up calling method 1 instead of method 2:

something.add("Hello", "World");

I ended up creating another method that looks like this:

//Method 3
void MyClass::add(const char* name, const char* value) {
    add(std::string(name), std::string(value));
}

It worked. So it would seem that when a method accepts a "quoted string" it will match in the following order:

  1. const char*
  2. bool
  3. std::string

Why would a quoted string be treated as a bool before a std::string? Is this the usual behavior? I have written a decent amount of code for this project and haven't had any other issues with the wrong method signature being selected...

+10  A: 

My guess is the conversion from pointer to bool is an implicit primitive type conversion, where the conversion to std::string requires the call of a constructor and the construction of a temporary.

280Z28
This is it. I had this problem once and it confused me, but your second parameter is a const char*, and that will be converted into a boolean.
GMan
+4  A: 

Pointers have an implicit conversion to bool. Perhaps you have seen the following:

void myFunc(int* a)
{
    if (a)
        ++(*a);
}

Now, in C++, implicit conversions between built-in types take precedence over conversions between class-types. So for example, if you had a class:

class Int
{
public:
    Int(int i) {}
}

And you overloaded a function for long and Int:

void test(long n) {cout << "long";}
void test(Int n) {cout << "Int";}

You'll see that the following code calls the long overload:

int i;
test(i);
rlbond
Note that std::string is "user-defined" too, despite being a defined by the standard. I think the more appropriate term is "class type" versus "non-class type".
MSalters
Good point. Edited.
rlbond
+4  A: 

In your case you have has overloaded functions. Overloading resolution occurs according to Section 13.3.

C++03 13.3.3.2/2:

When comparing the basic forms of implicit conversion sequences (as defined in 13.3.3.1)
— a standard conversion sequence (13.3.3.1.1) is a better conversion sequence than a user-defined conversion sequence or an ellipsis conversion sequence, and
— a user-defined conversion sequence (13.3.3.1.2) is a better conversion sequence than an ellipsis conversion sequence (13.3.3.1.3).

Conversion pointer into bool is a standard conversion. Conversion pointer into std::string is a user-defined conversion.

4.12 Boolean conversions An rvalue of arithmetic, enumeration, pointer, or pointer to member type can be converted to an rvalue of type bool. A zero value, null pointer value, or null member pointer value is converted to false; any other value is converted to true.

Kirill V. Lyadvinsky