c++隐式字符串到char*的转换匹配错误的函数签名

c++ implicit conversion of string to char* matches wrong function signature

本文关键字:错误 函数 转换 c++ 字符串 char      更新时间:2023-10-16

我正在编写一个程序,应该处理c字符串(char*)和c++字符串(std::string)。

#include <iostream>
#include <string>
void hello(std::string s) {
    std::cout << "STRING FUNCTION" << std::endl;
}
void hello(char* c) {
    std::cout << "CHAR FUNCTION" << std::endl;
}
int main(int argc, char* argv[]) {
    hello("ambiguous");
    hello((std::string)"string");
    hello((char*)"charp");
    return 0;
}

当我编译这个程序时,我得到警告:

test.cpp:14: warning: deprecated conversion from string constant to ‘char*’

关于对hello的第一次调用。运行程序得到:

CHAR FUNCTION
STRING FUNCTION
CHAR FUNCTION

表示第一次呼叫hello匹配的是hello(char* c)签名。

我的问题是,如果,作为一个c++程序,字符串字面值,("ambiguous")是一个std::字符串,为什么它会被强制转换为char*,然后匹配函数hello(char* c),而不是保持为std::字符串和匹配hello(std::string s) ?

我知道我可以用pragma或-Wsomething来警告(并且我可以毫无顾虑地将char*转换为string),但我想知道为什么编译器会费心做这种转换,如果有一种方法可以告诉它不要这样做。我正在编译g++ 4.4.3.

谢谢。

"ambiguous"这样的字符串字面值不是std::string类型。std::string是一个仅库类型,没有任何语言魔法。字符串字面值的类型实际上是const char[N],其中N是字面值的长度。

由于历史原因(向后兼容性),字符串字面值将隐式转换为char*(违反常量正确性)。这种内置转换优于"用户定义"到std::string的转换,这就是它调用char*函数并给出警告的原因。

如果您将hello的签名更改为hello(const char* c),它可能不会再给您警告(但仍然不会调用std::string版本,要做到这一点,您需要手动强制转换)。

你错了:"作为c++程序,字符串文字("ambiguous")是std::string"

("ambiguous")不是std::string,它是一个字符数组。

这就是为什么它调用void hello(char* c)