char*和std::string的过载安全吗?

4

我刚刚在一本初学者书籍上读到了关于函数重载的内容。 出于好奇,我想问一下,在char*和std::string之间进行重载是否安全。

我尝试使用以下代码,并得到了一些结果。但我不确定它是否是未定义的行为。

void foo(std::string str) {
  cout << "This is the std::string version. " << endl;
}

void foo(char* str) {
  cout << "This is the char* version. " << endl;
}

int main(int argc, char *argv[]) {

  foo("Hello"); // result shows char* version is invoked

  std::string s = "Hello";
  foo(s); // result shows std::string version

  return 0;

}

5
过载解析不应该导致我能想到的 UB。请注意,在 C++11 中将字符串字面量转换为 char * 是无效的。 - chris
@chris 谢谢你的建议。那么有没有解释为什么 foo("Hello") 会调用 char * 版本?我的担忧是,当 char* 不在场时,它也可能调用 std::string 版本。这与类型的接近程度有关吗?(即 "Hello" 是一个字面量,比 std::string 更接近 char*) - user3424826
const char[N]char * 的标准转换优先于用户定义的转换。 - chris
2个回答

8
是的,只要您将其设置为const char*,它就是安全的,并且通常非常有用。自C++11以来(在此之前已被弃用),字符串文字不能转换为char*const char*重载将被选择用于字符串字面值,因为字符串字面值是const char[N](其中N是字符数)。当多个重载函数可行时,它们有一种优先级排序方式,以决定选择哪一个。执行数组到指针转换比构造std::string更匹配,因此被认为是更好的匹配。
为什么重载std::stringconst char*会很有用呢?如果您有一个重载函数用于std::string,另一个用于bool,则在传递字符串字面值时将调用bool。这是因为bool重载仍然被认为是比构造std::string更好的匹配。我们可以通过提供const char*重载来解决这个问题,它将打败bool重载,并可以直接转发到std::string重载。

2

简短回答:完全安全。考虑以下用途:

foo("bar");//uses c string 
foo(std::string("bar") );//uses std::string
char* bar = "bar";
foo(bar);//uses c string
std::string bar_string = "bar";
foo(bar_string);//uses std::string
foo(bar_string.c_str()); //uses c string

警告,一些编译器(特别是启用c++11的编译器)要求在参数声明中使用const关键字,以允许使用临时字符串。

例如,为了得到以下代码: foo("bar"); 你需要这样写: void foo(const char* bar);


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接