为什么带引号的字符串在std :: string之前匹配bool方法签名?

时间:2009-07-19 02:36:39

标签: c++ string arguments boolean

考虑以下方法:

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

有效。因此,当方法接受“带引号的字符串”时,它将按以下顺序匹配:

  1. const char*
  2. bool
  3. std::string
  4. 为什么引用的字符串会在bool之前被视为std::string?这是通常的行为吗?我已为此项目编写了大量代码,并且在选择错误的方法签名时没有任何其他问题...

3 个答案:

答案 0 :(得分:14)

我的猜测是从指针到bool的转换是一种隐式原始类型转换,转换为std::string需要调用构造函数和构造临时。

答案 1 :(得分:9)

在您的情况下,您的功能已超载。根据第13.3节进行重载分辨率。

C ++ 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布尔转换   算术,枚举,指针的右值或成员类型的指针可以转换为 bool 类型的右值。零值,空指针值或空成员指针值转换为false;任何其他值都转换为true。

答案 2 :(得分:6)

指针隐式转换为bool。也许您已经看到以下内容:

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

现在,在C ++中,内置类型之间的隐式转换优先于类类型之间的转换。例如,如果你有一个类:

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

您重载了longInt的函数:

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

您将看到以下代码调用长重载:

int i;
test(i);