我正在编写一个程序,应该处理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)