为啥 std::string 引用不能采用 char*?

Posted

技术标签:

【中文标题】为啥 std::string 引用不能采用 char*?【英文标题】:Why std::string reference cannot take char*?为什么 std::string 引用不能采用 char*? 【发布时间】:2017-05-31 04:36:20 【问题描述】:

我有简单的代码。

template<typename T>
class NamedObject
public:

    NamedObject(std::string& name, const T& value):nameValue(name), objectValue(value)
    

    

private:
    std::string& nameValue;
    const T objectValue;
;

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

    NamedObject<int> no1("Smallest Prime Number",2);//error
    NamedObject<int> no2(std::string("Smalledst Prime Number"),2);//works

    return 0;

当我将第一个参数设为非引用时,会创建 no1 和 no2 对象。但是当我继续参考 Visual Studio 编译器时会出现以下错误,

错误 1 ​​错误 C2664: 'NamedObject::NamedObject(std::string &,const T &)' : 无法将参数 1 从 'const char [22]' 转换为 'std::string &' c:\users\pkothari\documents\visual studio 2008\projects\stackoflw\stackoflw\stackoflw.cpp 36

如果 char * 可以转换为 std::string,为什么不能转换为 std::string& ?有什么办法让它工作吗?

【问题讨论】:

绑定引用≠构造实例 另一件需要考虑的事情:那不是char * @user4581301 const char*? 要解决这个问题,你的函数应该接受std::string const&amp; name @PranitKothari 在进行更改后,您应该会看到出现了不同的错误消息(与函数参数传递无关)。您还必须#include &lt;string&gt;,并将类成员std::string&amp; nameValue; 更改为std::string nameValue;。 Working example 【参考方案1】:
NamedObject<int> no2(std::string("Smalledst Prime Number"),2);//works

这不应该在符合标准的编译器中工作。 MS Visual Studio C++ 支持它,即使它不是标准 C++。

当预期参数为 std::string&amp; 时,以下调用均不适用。

NamedObject<int> no1("Smallest Prime Number",2);
NamedObject<int> no2(std::string("Smalledst Prime Number"),2);

当参数类型为std::stringstd::string const&amp; 时,它们都应该工作。

【讨论】:

编译器不会为std::string("Smalledst Prime Number")创建无名对象吗? 我喜欢 msvc 扩展如此频繁地误导 @PranitKothari,这正是它不能绑定到非const 引用的原因。 仅更改参数类型会导致运行时UB,因为该类将包含一个悬空引用 @M.M:实际上,仅更改参数类型将导致编译时错误,因为您无法使用std::string const&amp; 参数初始化std::string&amp; 成员。但根本风险确实存在:引用成员确实很容易导致悬空引用。当引用成员不明显时尤其如此。 (std::pair&lt;int&amp;,int&amp;&gt; 有明显的参考成员)

以上是关于为啥 std::string 引用不能采用 char*?的主要内容,如果未能解决你的问题,请参考以下文章

为什么std :: runtime_error的c'tor采用对std :: string的常量引用?

为啥在 GCC 5.1 中仍然启用 COW std::string 优化?

为啥'=='在std :: string上很慢?

SWIG:如何包装 std::string&(通过引用传递的 std::string)

为啥 g++ 不关心初始化列表分配给 (const std::string&) a (std::string)?和其他怪异[关闭]

为啥 std::string 零初始化为不确定值