为什么编译器更喜欢使用f(const void*)而不是f(const std::string&)?

46

考虑以下代码:

#include <iostream>
#include <string>

// void f(const char *) { std::cout << "const char *"; } // <-- comment on purpose
void f(const std::string &) { std::cout << "const std::string &"; }
void f(const void *) { std::cout << "const void *"; }

int main()
{
    f("hello");
    std::cout << std::endl;
}

我使用g++ (Ubuntu 6.5.0-1ubuntu1~16.04) 6.5.0 20181026编译了这个程序:

$ g++ -std=c++11 strings_1.cpp -Wall
$ ./a.out

const void *

请注意,这个注释是有意为之以进行测试的,否则编译器会使用f(const char *)

那么,为什么编译器选择f(const void*)而不是f(const std::string &)


5
这是标准的相关部分:http://eel.is/c++draft/over.ics.rank#2.1 - geza
@geza 太棒了。我正在寻找它,谢谢。 - omar
这里的重载解析规则在许多C++版本中都是简单且不变的。 - curiousguy
4
一个字符串字面量并不是一个std::string,它是一个char类型的静态数组,它会衰减成指向其第一个字符的指针。这个行为是从C语言继承下来的,因为C从未有过像std::string这样的东西,但大量的代码都处理字符串。 - cmaster - reinstate monica
1
如果您特别想要一个 std::string 文字,可以在文字后添加s来实现。这是一种自定义字面值,自C++14以来就可用。https://en.cppreference.com/w/cpp/string/basic_string/operator%22%22s - henje
显示剩余2条评论
1个回答

54

将其转换为std :: string 需要进行“用户定义的转换”。

转换为 void const * 则不需要。

用户定义的转换在内置转换之后排序。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接