Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/149.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;函数重载优先级_C++_Overloading - Fatal编程技术网

C++ C++;函数重载优先级

C++ C++;函数重载优先级,c++,overloading,C++,Overloading,为什么代码会给出一个输出:bool? 有没有办法让常量char*与字符串版本匹配 #include <string> #include <iostream> void func(bool) { std::cout << "bool" << std::endl; } void func(const std::string&) { std::cout << "string" << std::endl;

为什么代码会给出一个输出:
bool
? 有没有办法让
常量char*
字符串
版本匹配

#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");
}
#包括
#包括
无效函数(布尔)
{

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

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

void func(const char* arg)
{
    func(std::string{arg});
}
func(std::string("hello"));
要回答原因:

函数匹配是编译器在重载集中选择要调用的函数的过程。 这里有两个可行的候选函数(您定义的两个函数)。要选择一个,编译器将它们所表示的转换进行排序

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

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

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

比较隐式转换序列的基本形式时 定义见13.3.3.1)(2.1)-标准转换顺序 (13.3.3.1.1)是比用户定义的转换序列更好的转换序列 转换序列或省略号转换序列,以及(2.2)-a 用户定义的转换顺序(13.3.3.1.2)是更好的转换 序列比省略号转换序列(13.3.3.1.3)更精确

因此,由于
char const*
bool
的隐式转换是标准的隐式转换,因此与到
std::string
的隐式转换相比,作为用户定义的转换是更好的转换,并且在重载解析中是首选的

要强制重载解析,请选择
std::string
版本:

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

func(std::string(“hello”))
任何没有明确构造
std::string
的替代方法?我希望编译器给出一个模糊的警告,而不是匹配
bool
版本。可能有编译器选项,但它将依赖于编译器gcc@prmottajr我在叮当声上尝试了
-Wall
,但没有显示任何警告。您没有收到警告不明确的警告,因为调用不是模糊的。谢谢Angew!所以C++的底漆是很不自然的……(61.1)你能解释操作符<代码> {} /Cube >吗?那是C++ 11的特性。这看起来是唯一的直截了当的答案,解释语言如何工作而不把任何责任归咎于“编译器”。“@KerrekSB”语言实际上不是由一致性编译器所定义的吗?@Angew:这是一种极其反常的看待世界的方式,但我想你可以这样看待它…@KerrekSB我实际上不是这样看待世界的(尽管有1.1/1和1.4/2)。只是我看不到说什么之间有多大的区别“语言决定了这一点”和“编译器这样做”。只要编译器遵循这个标准,我就认为这两个等价物。@ Angew:即使你从来没有编译它,代码也是有意义的。你可以谈论表达式<代码> f(x)。
没有编译代码,重载解析仍然是相关的。代码和逻辑比编译行为更重要。用编译的辅助思考来污染代码讨论似乎是毫无意义的噪音和干扰。为什么不也讨论一下用粉色漫画SAN打印的代码会是什么样子呢?