无法初始化类型 "std::string&"(非常量限定)的引用

a reference of type "std::string&" (not const-qualified) cannot be initialized

本文关键字:常量 引用 非常 初始化 类型 std string      更新时间:2023-10-16

当我试图编译以下函数时,我得到了错误。

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]"

您的代码有两个问题。首先,"Hello World!"char const[13]而不是std::string。所以编译器必须(隐式地)将其转换为CCD_ 4。结果转换是暂时的(C++语言中的右值),不能使用临时初始化对非常量的引用。第二个是即使您可以(或者您声明函数返回引用const),则返回对某个对象的引用将立即超出范围(从而被销毁);任何使用所产生的引用将导致未定义的行为。

真正的问题是:为什么引用?除非你真的指的是物体中寿命较长的东西客户端代码修改它的意图(通常不是一个好主意,但是有一些明显的例外,比如向量的operator[]),您应该按值返回。

"Hello World"不是字符串,它是一个char数组。c++编译器需要将其转换为字符串值,而不是字符串引用(因为它不是字符串),所以您的函数应该看起来像:

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

为了扩展(应OP的要求),编译器会执行以下操作:

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

值s由std::string复制构造函数从函数中复制出来。

您正在指示编译器返回从char数组"Hello World"创建的临时std::字符串。它需要把它放在某个地方,并有人负责清理。你可以通过几种方式做到这一点:

  • 返回auto_ptr
  • 返回字符串对象
  • 返回对字符串对象的const引用(尽管这确实给我留下了一个问题,谁来清理它?)
  • (仅限c++0x)返回对std::字符串的右手引用。(std::string&&)

第二个可能是最简单的。编译器将使用RVO(返回值优化)来删除它调用的副本。

就这么做吧。

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

仔细聆听


要了解这个问题及其解决方案,您必须了解编译器的一些工作。但是,别担心,我会解释并尽可能简单。

字符串&foo()字符串foo(

在第一个例子中,我们希望返回一个";参考文献";到一个已经创建的字符串,它应该有一个内存地址(我的意思是,一个左值)。如果我们返回,像这样:

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

它永远不会起作用,因为你可能有原因。字符串:";示例字符串";是一个Temporary值,没有内存地址,因为它尚未构造。它必须在任何字符串变量内部的某个地方构造,在那里它将被分配给内存地址。目前,它没有内存地址(我指的是右值)。

类似地,在第二种情况下,如果我们这样做:

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

在这里,我们实际上正在构建一个类型为String的新变量,从这里调用它。例如,如果我们做这样的事情:

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

将在Equality运算符的右侧创建一个字符串变量,并将数据复制到Test变量(如果禁用编译器优化)。但是等等,还有其他的东西。

什么是:常量字符串&foo()


以下是编译器的一些神奇之处 .在不使事情复杂化的情况下:),我只想说,它具有string&foo()字符串foo(。

这意味着如果我们做这样的事情:

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

这将返回(常数)"0";参考文献";到字符串测试。这很明显。但是,如果我们这样做:

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

编译器将智能地为"0"创建临时寄存器(在程序集中);示例字符串";并将其存储在那里。然后,它将向您返回对该Register的引用。这个Register事件只发生在constReference的情况下。

结论


使用常量字符串&foo()来解决您的问题,您可能知道我们这样做的原因:)。如果你想了解更多,请查看C++中的类型系统主题。快乐学习。

我想你想要:

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