为啥编译器更喜欢 f(const void*) 而不是 f(const std::string &)?
Posted
技术标签:
【中文标题】为啥编译器更喜欢 f(const void*) 而不是 f(const std::string &)?【英文标题】:Why does the compiler prefer f(const void*) to f(const std::string &)?为什么编译器更喜欢 f(const void*) 而不是 f(const std::string &)? 【发布时间】:2019-04-20 14:36:00 【问题描述】:考虑以下代码:
#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 &)
?
【问题讨论】:
这里是标准的相关部分:eel.is/c++draft/over.ics.rank#2.1 @geza 真棒。我正在找它,谢谢。 这里的重载解析规则很简单,在很多C++版本中没有变化。 嗯,字符串文字不是std::string
,它是char
s 的静态数组,它衰减为指向其第一个字符的指针。 这种行为继承自 C,它从来没有像 std::string
这样的东西,但仍然有大量的代码处理字符串。
如果您特别想要 std::string
文字,您可以通过在文字后面添加 s
来实现。这是一个用户定义的文字,自 C++14 起可用。 en.cppreference.com/w/cpp/string/basic_string/operator%22%22s
【参考方案1】:
转换为std::string
需要“用户定义的转换”。
转换为void const*
不会。
用户定义的转换在内置转换之后排序。
【讨论】:
以上是关于为啥编译器更喜欢 f(const void*) 而不是 f(const std::string &)?的主要内容,如果未能解决你的问题,请参考以下文章
为啥 ostream::write() 在 C++ 中需要“const char_type*”而不是“const void*”?
为啥将“float**”转换为“const float**”时出现错误?