C++函数重载优先级

C++ function overload priority

为什么代码会给出输出:bool? 有什么方法可以使 const char*string 版本相匹配?

#include <string>
#include <iostream>

void func(bool)
{
    std::cout << "bool" << std::endl;
}

void func(const std::string&)
{
    std::cout << "string" << std::endl;
}

int main(int argc, char* argv[])
{
    func("hello");
}

发生这种情况是因为编译器更喜欢内置转换而不是用户定义的转换。从指针到 bool 的转换是内置的,因此选择重载而不是构造 std::string.

您可以添加一个重载,它接受 const char* 并将其转发到 std::string 版本:

void func(const char* arg)
{
    func(std::string{arg});
}

回答原因:

函数匹配是编译器在重载集中选择调用哪个函数的过程。 在这里,有两个可行的候选者(您定义的两个函数)。为了选择一个,编译器对它们暗示的转换进行排名。

第一个候选 void func(bool) 表示数组到指针的转换,然后是布尔转换(从 const char[6]const char* 再到 bool) 第二个候选意味着用户定义的转换(调用 std::string ctor 接受 const char*

第二次转换排名较低,因此选择第一个候选作为最佳匹配。

根据标准 N4431 §13.3.3.2/2 排名隐式转换序列 [over.ics.rank] (强调我的) :

When comparing the basic forms of implicit conversion sequences (as defined in 13.3.3.1) (2.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 (2.2) — 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).

因此,因为 char const *bool 是标准的隐式转换,相比之下 std::string 的隐式转换是用户定义的转换,是更好的转换并且是首选在重载决议中。

为了强制重载解析选择 std::string 版本:

func(std::string("hello"));