将`char []`传递给接受`std :: string&`的函数是不是是一种好习惯

Posted

技术标签:

【中文标题】将`char []`传递给接受`std :: string&`的函数是不是是一种好习惯【英文标题】:Is it good practice to pass `char []` to a function which accepts `std::string&`将`char []`传递给接受`std :: string&`的函数是否是一种好习惯 【发布时间】:2018-11-17 07:55:18 【问题描述】:

我没有遇到以下代码的任何问题,但是将char [] 传递给接受std::string& 作为参数的函数是一种好习惯

 const char* function(std::string& MyString)
 
    MyString = "Hello World";
    return MyString.c_str();
 

 int main()
 
    char MyString[50];

    /*
    *Is it good practice to cast like this?
    *what possible issues i could face because of this casting?
    */
    function((std::string)MyString);                  

    std::cin.get();
    return 0;
 

【问题讨论】:

这取决于函数的细节。在这种情况下,如果您尝试将function 的返回值保存到您调用它的行之后,它实际上将不起作用,因为返回值仅与您调用它的字符串一样长。但这是一个稍微不同的问题。仅从创建临时对象的角度考虑生命周期管理会遗漏一些东西。一般来说,它可能涉及不必要的副本来构造std::string;如果需要,您可以这样做,但最好编写函数以使用 std::string_view 代替。 【参考方案1】:

这根本行不通,因为它需要创建不能绑定到左值引用的临时std::string。即使函数引用了std::string const 临时创建也会对性能产生影响。因此,根据函数的性质,添加一个接受指向 c 字符串的指针的重载可能是个好主意。或者,如果函数不打算修改字符串,你可以让它接受std::string_view,这样它就可以处理std::string 和c-strings。

【讨论】:

是的 VC++ 允许它 @AlanBirtles @BreakBadSP 您很可能在非一致性模式下编译。使用/permissive-/Zc:rvalueCast【参考方案2】:

不,这是不好的做法,因为演员表没有效果; std::string 可以使用非显式构造函数从 char * 构造,因此您可以删除强制转换,您将获得完全相同的代码(只是使用隐式构造而不是显式强制转换)。

现在,您会收到一个错误(至少对于未损坏的编译器),因为您无法将临时对象传递给非常量左值引用。但是如果你把函数改成const std::string &,它就可以正常工作了。

同样不好的做法是返回您通过调用 std::string::c_str() 获得的char *——这个指针只有在字符串对象没有被修改或破坏时才有效——所以返回的指针一旦您作为参数传递的 temp 被销毁,它将变得无效(悬空)。如果你将返回的指针保存在 main 中的局部变量中,然后尝试对它做一些事情(比如打印它),那将是未定义的行为。

【讨论】:

【参考方案3】:

简而言之,将char[] 传递给接受字符串的函数是常见的做法(来自C)。而且还不错。显式演员在这里不好。该功能也不好,因为它不接受传递char[] ...

【讨论】:

另外,如果您使用引用,因为您需要在函数内更改字符串(这应该是调用者可见的结果),如果有string,则不能使用char[](或其他东西) .好不好又是个问题。

以上是关于将`char []`传递给接受`std :: string&`的函数是不是是一种好习惯的主要内容,如果未能解决你的问题,请参考以下文章

如何将 std::string 传递给需要 char* 的函数? [复制]

Swig:将 std::vector<unsigned char> 传递给从 c++ 生成的 c# 函数

为什么将`const char [N]`和`const char *`传递给view :: c_str()会产生不同的二进制文件,而string_view会产生相同的结果吗?

传递给第三方 API 时的 C++ const std:string& 安全性

如何将 std::ofstream& 传递给功能参数?

传递给 std::basic_string 的分配器能否将其方法设为虚拟