简体   繁体   English

C ++将字符串隐式转换为char *匹配错误的函数签名

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

I am writing a program which is supposed to handle both c strings (char*) and c++ strings (std::string). 我正在编写一个程序,它应该处理c字符串(char *)和c ++字符串(std :: string)。 I have isolated by concern to the example below. 我出于关注而孤立了以下示例。

#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;
}

When I compile this program, I get the warning: 当我编译该程序时,我得到警告:

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

regarding the first call to hello . 关于第一次hello Running the program gives: 运行该程序可以得到:

CHAR FUNCTION
STRING FUNCTION
CHAR FUNCTION

showing that the first call to hello is matching the signature hello(char* c) . 显示对hello的第一次调用与签名hello(char* c)匹配。

My question is, if, as a c++ program, a string literal, ( "ambiguous" ) is a std::string, why would it be cast to a char* and then match the function hello(char* c) rather than staying as a std::string and matching hello(std::string s) ? 我的问题是,如果作为c ++程序,字符串文字(( "ambiguous" ))是std :: string,为什么将其转换为char*然后匹配函数hello(char* c)而不是留下作为std :: string并匹配hello(std::string s)吗?

I know I can pragma or -Wsomething out the warning (and that I can cast char* to string without concern), but I want to know why the compiler would even bother doing this cast and if there is a way to tell it not to. 我知道我可以进行杂注或-发出警告(并且我可以将char *转换为字符串而无需担心),但是我想知道为什么编译器甚至会费心进行此转换,以及是否有办法告诉它不要。 I am compiling with g++ 4.4.3. 我正在使用g ++ 4.4.3进行编译。

Thank you. 谢谢。

String literals like "ambiguous" are not of type std::string . "ambiguous"这样的字符串文字的类型不是std::string std::string is a library only type, with no language magic whatsoever. std::string是仅库类型,没有任何语言魔力。 The type of a string literal is actually const char[N] , where N is the length of the literal. 字符串文字的类型实际上是const char[N] ,其中N是文字的长度。

For historical reasons (backward compatibility) string literals will implicitely convert to char* (violating const-correctness). 由于历史原因(向后兼容),字符串文字将隐式转换为char* (违反const-correctness)。 This builtin conversion is prefered to the "user defined" conversion to std::string , which is why it calls the char* function and gives you the warning. 与“ std::string ”的“用户定义”转换相比,此内置转换更可取,因此它会调用char*函数并向您发出警告。

If you change the signature of hello to hello(const char* c) it will probably not give you a warning anymore (but still won't call the std::string version, to do that you need a manual cast). 如果更改签名hellohello(const char* c)它可能不会给你了一个警告(但仍然不会调用std::string版本,要做到这一点,你需要手动施放)。

您错了:“作为c ++程序,字符串文字(“模糊”)是std :: string”

("ambiguous") is not a std::string, it is an array of characters. (“模棱两可”)不是std :: string,而是字符数组。

That's why its calling void hello(char* c). 这就是为什么它调用void hello(char * c)的原因。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM