我正在编写一个程序,它应该同时处理 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::string,为什么它会被转换为一个 char*
然后匹配函数 hello(char* c)
而不是保留为 std::string 并匹配 hello(std::string s)
?
我知道我可以 pragma 或 -Wsomething 排除警告(并且我可以毫无顾虑地将 char* 转换为字符串),但我想知道为什么编译器甚至会费心进行这种转换,以及是否有办法告诉它不是。我正在使用 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++字符串到char *的隐式转换匹配错误的函数签名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15535729/