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

Bea*_*sen 14 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);
Run Code Online (Sandbox Code Playgroud)

看起来以下代码最终会调用方法1而不是方法2:

something.add("Hello", "World");
Run Code Online (Sandbox Code Playgroud)

我最终创建了另一个看起来像这样的方法:

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

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

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

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

Sam*_*ell 14

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

  • 就是这个.我曾经遇到过这个问题而且它让我很困惑,但你的第二个参数是一个const char*,它将被转换成一个布尔值. (2认同)

Kir*_*sky 9

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

C++ 03 13.3.3.2/2:

比较隐式转换序列的基本形式(如13.3.3.1中所定义)
- 标准转换序列(13.3.3.1.1)是比用户定义的转换序列或省略号转换序列更好的转换序列,并且
- a用户定义的转换序列(13.3.3.1.2)是一个比省略号转换序列(13.3.3.1.3)更好的转换序列.

将指针转换为bool是标准转换.转换为std :: string的指针是用户定义的转换.

4.12布尔转换 可以将算术,枚举,指针或指向成员类型的指针的右值转换为bool类型的右值.零值,空指针值或空成员指针值转换为false; 任何其他值都转换为true.


rlb*_*ond 6

指针有一个隐含的转换bool.也许您已经看到以下内容:

void myFunc(int* a)
{
    if (a)
        ++(*a);
}
Run Code Online (Sandbox Code Playgroud)

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

class Int
{
public:
    Int(int i) {}
}
Run Code Online (Sandbox Code Playgroud)

你为long和重载了一个函数Int:

void test(long n) {cout << "long";}
void test(Int n) {cout << "Int";}
Run Code Online (Sandbox Code Playgroud)

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

int i;
test(i);
Run Code Online (Sandbox Code Playgroud)