我正在编写一个程序,它应该处理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*
然后匹配函数{ {1}}而不是保持std :: string并匹配hello(char* c)
?
我知道我可以编写pragma或-Wsomeout警告(并且我可以无需关心地将char *转换为字符串),但我想知道为什么编译器甚至会打扰这个演员如果有办法告诉它没有。我正在使用g ++ 4.4.3进行编译。
谢谢。
答案 0 :(得分:4)
"ambiguous"
之类的字符串文字不属于std::string
类型。 std::string
是一种仅限库的类型,没有任何语言魔法。字符串文字的类型实际上是const char[N]
,其中N
是文字的长度。
由于历史原因(向后兼容性),字符串文字将隐含地转换为char*
(违反const-correctness)。此内置转换优先于“用户定义”转换为std::string
,这就是它调用char*
函数并向您发出警告的原因。
如果您将hello
的签名更改为hello(const char* c)
,它可能不会再向您发出警告(但仍然不会调用std::string
版本,为此您需要手动演员)。
答案 1 :(得分:0)
你错了:“作为一个c ++程序,一个字符串文字,(”模棱两可“)是一个std :: string”
答案 2 :(得分:0)
(“ambiguous”)不是std :: string,而是一个字符数组。
这就是为什么它调用void hello(char * c)。