简体   繁体   English

无法初始化“std::string&”类型的引用(非 const 限定)

[英]a reference of type “std::string&” (not const-qualified) cannot be initialized

When I try to compile the following function I get the error.当我尝试编译以下 function 时出现错误。

string& foo(){
return "Hello World";
}


Error:
1   IntelliSense: a reference of type "std::string &" (not const-qualified) cannot be initialized with a value of type "const char [12]"

There are two problems with your code.您的代码有两个问题。 First, "Hello World!"首先, "Hello World!" is a char const[13] , not an std::string .char const[13] ,而不是std::string So the compiler has to (implicitly) convert it to an std::string .因此编译器必须(隐式)将其转换为std::string The result of a conversion is a temporary (rvalue in C++-speak), and you cannot initialize a reference to a non-const with a temporary.转换的结果是一个临时的(C++ 中的右值),并且您不能使用临时初始化对非常量的引用。 The second is that even if you could (or you declared the function to return a reference to const), you're returning a reference to something which will immediately go out of scope (and thus be destructed);第二个是即使你可以(或者你声明了 function 以返回对 const 的引用),你返回的引用将立即从 Z31A1FD140BE4BEF2D11E121EC9A18A 中取出 go (因此被破坏)5; any use of the resulting reference will result in undefined behavior.对结果引用的任何使用都将导致未定义的行为。

The real question is: why the reference?真正的问题是:为什么要引用? Unless you're actually referring to something in an object with a longer lifetime, with the intent that the client code modify it (usually not a good idea, but there are notable exceptions, like operator[] of a vector), you should return by value.除非您实际上指的是 object 中具有更长生命周期的东西,目的是客户端代码修改它(通常不是一个好主意,但有明显的例外,例如矢量的operator[] ),您应该返回按价值。

"Hello World" isn't a string, it is an array of char. “Hello World”不是一个字符串,它是一个字符数组。 The c++ compiler needs to convert this into a string value, not a string reference (because it's not a string), so your function should look like: c++ 编译器需要将其转换为字符串值,而不是字符串引用(因为它不是字符串),因此您的 function 应如下所示:

string foo(){
    return "Hello World";
}

To expand (at the OP's request) the compiler does something like this:要扩展(应 OP 的要求),编译器会执行以下操作:

string foo(){
    char a[] = "Hello World";
    string s( a ); 
    return s;
}

The value s is copied out of the function by the std::string copy constructor.值 s 由 std::string 复制构造函数从 function 中复制出来。

You're instructing the compiler to return a temporary std::string created from the char array "Hello World".您正在指示编译器返回从 char 数组“Hello World”创建的临时 std::string。 It needs to put this somewhere and have somebody responsible for cleaning it up.它需要把它放在某个地方,并有人负责清理它。 You can do that in a few ways:您可以通过以下几种方式做到这一点:

  • Return an auto_ptr返回一个 auto_ptr
  • Return a string object返回一个字符串 object
  • Return a const reference to a string object (although this does leave me with the question who cleans it up?)返回对字符串 object 的 const 引用(尽管这确实给我留下了谁清理它的问题?)
  • (c++0x only) Return a right-hand-reference to an std::string. (仅限 c++0x)返回对 std::string 的右手引用。 (std::string &&) (std::string &&)

The second would probably be the easiest.第二个可能是最简单的。 The compiler will use RVO (return value optimization) to remove the copy invoked by that.编译器将使用 RVO(返回值优化)来删除由它调用的副本。

Just do this.就这样做吧。

const string foo() {
    return string("Hello World");
}

I think you want:我想你想要:

string foo(){
    return "Hello World";
}

Listen Carefully仔细听


To understand the issue, and its solution, you have to understand some working of the Compiler.要了解该问题及其解决方案,您必须了解编译器的一些工作原理。 But, don't worry, I will explain and will keep it simplest as possible.但是,别担心,我会解释并尽可能保持简单。

string& foo() vs string foo()字符串& foo()字符串 foo()

In the first example, we want to return a "Reference" to an already created string, which should have a memory address (I mean, an lvalue).在第一个示例中,我们希望将“引用”返回给已创建的字符串,该字符串应具有 memory 地址(我的意思是左值)。 If we return, like this:如果我们返回,像这样:

string& foo()
{
     return "Example String";
}

It'll never work, because you may have got the reason.它永远不会起作用,因为你可能已经找到了原因。 The String: "Example String" is a Temporary value, having no memory address, because it's not constructed yet.字符串:“示例字符串”是一个临时值,没有 memory 地址,因为它尚未构造。 It has to be constructed somewhere, inside of any string variable, where it will be assigned to a memory address.它必须在任何字符串变量内部的某个地方构造,在那里它将被分配给 memory 地址。 Currently, it's having no memory address (I mean rvalue).目前,它没有 memory 地址(我的意思是右值)。

Similarly, in the 2nd case, if we do something like this:同样,在第二种情况下,如果我们这样做:

string foo()
{
     return "Example String";
}

Here, we are actually constructing a new Variable of type String, from where it's being called.在这里,我们实际上是在构造一个 String 类型的新变量,从那里调用它。 For example, if we do something like this:例如,如果我们这样做:

int main()
{
     string Test = foo();
}

A string variable will be created on the Right Side of the Equality Operator, and the Data will be copied to the Test variable (If compiler optimization is disabled).将在等式运算符的右侧创建一个字符串变量,并将数据复制到测试变量(如果禁用编译器优化)。 But wait, there's something else too.但是等等,还有别的东西。

What is: const string& foo() ?什么是: const string& foo()


Here lies some Compiler's Magic.这里有一些编译器的魔法。 Without making things complicated:), I will just say, it has features of string& foo() and of string foo() too, with some additional ones.不让事情变得复杂:),我只想说,它也有string& foo()string foo()的特性,还有一些额外的特性。

This means if we do something like this:这意味着如果我们这样做:

const string& foo()
{
    string Test = "Example String";
    return Test;
}

This will return the (constant) "Reference" to the string Test.这会将(常量)“引用”返回到字符串 Test。 It's quite obvious.这很明显。 But, if we do something like this:但是,如果我们这样做:

const string& foo()
{
    return "Example String";
}

The compiler will Intelligently create a temporary Register (in Assembly) for "Example String" and store it there.编译器将为“示例字符串”智能地创建一个临时寄存器(在汇编中)并将其存储在那里。 Then, it'll return you the reference to that Register.然后,它将返回对该寄存器的引用。 This Register thing only happens in the case of const Reference.这个 Register 事情只发生在 const Reference 的情况下。

Conclusion结论


Use const string& foo() to solve your problem, and you may know the reason why are we doing so:).使用const string& foo()来解决您的问题,您可能知道我们这样做的原因:)。 If you wanna learn more, check for the topics of Type System in C++.如果您想了解更多信息,请查看 C++ 中的类型系统主题。 Happy Learning.快乐学习。

暂无
暂无

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

相关问题 &#39;std::string&amp; 类型的非常量引用的无效初始化 - invalid initialization of non-const reference of type ‘std::string& 将 const 限定的 object 传递给“std::move” - Passing the const-qualified object to the 'std::move' 递归模板化 function 无法分配给具有 const 限定类型“const tt &”的变量“state” - Recursive templated function cannot assign to variable 'state' with const-qualified type 'const tt &' 是初始化类型“int&”(非const限定)类型的引用,类型为“bool”的某些hack? - Is initializing a reference of type “int &” (not const-qualified) with a value of type “bool” some hack? 无法从const TiXmlString转换为const std :: string& - Cannot convert from const TiXmlString to const std::string& 类型std :: string&的非常量引用的无效初始化-如何删除 - invalid initialization of non-const reference of type std::string& - how to remove 如何修复编译错误:类型“std::__1::string&amp;”的非常量引用的初始化无效 - How fix compile error: invalid initialization of non-const reference of type 'std::__1::string& 为什么std :: basic_ostream :: operator &lt;&lt;不符合const资格? - why is std::basic_ostream::operator<< not const-qualified? 从类型&#39;std :: basic_string的右值对类型&#39;std :: string&的非常量引用进行了无效的初始化<char> - invalid initialization of non-const reference of type ‘std::string& from an rvalue of type ‘std::basic_string<char> 从NSString转换为“ const std :: string&” - Casting from NSString to “const std::string&”
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM