2

我正在编写一个程序,它应该同时处理 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,为什么将它转换为 achar*然后匹配函数hello(char* c)而不是保持为 std::string 和匹配hello(std::string s)

我知道我可以 pragma 或 -Wsomething 发出警告(并且我可以将 char* 转换为字符串而无需担心),但我想知道为什么编译器甚至会费心进行这种转换,以及是否有办法告诉它不要. 我正在使用 g++ 4.4.3 进行编译。

谢谢你。

4

3 回答 3

5

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

由于历史原因(向后兼容性),字符串文字将隐式转换为char*(违反 const 正确性)。此内置转换优于“用户定义”转换为std::string,这就是它调用char*函数并向您发出警告的原因。

如果您将签名更改hellohello(const char* c)它可能不会再给您警告(但仍然不会调用该std::string版本,为此您需要手动转换)。

于 2013-03-20T22:22:15.693 回答
0

你错了:“作为一个 C++ 程序,一个字符串文字,(“歧义”)是一个 std::string”

于 2013-03-20T22:14:32.257 回答
0

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

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

于 2013-03-20T22:22:15.977 回答