为啥编译器更喜欢 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 &amp;)

【问题讨论】:

这里是标准的相关部分:eel.is/c++draft/over.ics.rank#2.1 @geza 真棒。我正在找它,谢谢。 这里的重载解析规则很简单,在很多C++版本中没有变化。 嗯,字符串文字不是std::string,它是chars 的静态数组,它衰减为指向其第一个字符的指针。 这种行为继承自 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**”时出现错误?

为啥游戏逻辑更喜欢 update() 而不是 didFinishUpdate?

为啥 JSLint 更喜欢点符号而不是方括号?

为啥clang++更喜欢adcx而不是adc