【问题标题】:passing a string literal to a function that takes a std::string&将字符串文字传递给采用 std::string& 的函数
【发布时间】:2010-10-28 15:13:24
【问题描述】:

我有以下功能

void AddNodeValue(XMLNode& node, std::string& value);

我想这样使用它:

document.AddNodeValue(modvalue,"modvalue");

编译器抱怨:

error C2664: 'void XML::XMLDocument::AddNodeValue(XML::XMLNode &,std::string &)' : cannot convert parameter 2 from 'const char [9]' to 'std::string &'
        A reference that is not to 'const' cannot be bound to a non-lvalue

我不明白为什么这是错误的?

编译器:VS2003

【问题讨论】:

    标签: c++ string function


    【解决方案1】:

    您的函数需要使用const std::string& 才能这样使用它。

    C++ 有一个规则,即右值(在您的情况下,是从字符串文字创建的临时 std::string)可以与 const 引用绑定,但不能与非 const 引用绑定。

    据我所知,这个限制不是由于任何基本的实现问题,因为临时值可以以其他方式修改。但是假设一个采用非常量引用的函数会这样做,因为它的主要目的是修改该参数。用一个临时的来做这件事通常没有多大意义,所以可能禁止它捕获错误远远超过它阻止人们做一些有价值的事情。无论如何,并不是所有的右值都是临时的:有些是真的不能修改的文字。

    如果您无法更改函数 AddNodeValue,那么您可以解决它:

    std::string valstr("modvalue");
    document.AddNodeValue(modvalue, valstr);
    // valstr might have changed, check the documentation of AddNodeValue
    

    【讨论】:

    • 基本上存在强制引用语义的限制。引用旨在与有效和持久的对象一起使用。当然,您可以通过返回对本地值的引用来创建无效引用,但这是语义错误。
    • @Let_Me_Be: 对(假设“引用”是指“非 const 引用”——显然 const 引用并不意味着只用于持久对象)。那么,下一个问题是 为什么 非 const 引用要与有效和持久的对象一起使用,而 AFAIK 是因为修改“吨。 C++0x 为有效但不持久的对象提供了一种新的引用类型,这对于那些需要修改这些对象确实有意义的场合非常有用。
    • 是的,C++0x 提供左值引用。整个引用点(内部仍然是一个指针)是它受到严重限制(通过绑定到一些现有对象,非空等......)。因此,编译器可以提供更多有趣的优化。
    • @Let_Me_Be: 是的,但是你所说的对于 const 和非常量引用没有任何不同,所以你所说的任何内容都不能解释一个可以绑定到右值的规则,并且另一个不能。对此的解释在别处,这就是我(我承认)猜测的。引用是否在内部是“仍然指针”是一个实现细节,而可以对引用进行良好优化的情况恰恰是在幕后没有任何指针的情况。
    • 对于 const 这条规则无关紧要。您只能从常量中读取,因此它在命令之后是否停止存在并不重要。
    猜你喜欢
    • 2021-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-24
    • 1970-01-01
    • 2020-12-17
    相关资源
    最近更新 更多