无法初始化类型 "std::string&"(非常量限定)的引用
a reference of type "std::string&" (not const-qualified) cannot be initialized
当我试图编译以下函数时,我得到了错误。
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";
}
- 什么时候在C++中返回常量引用是个好主意
- 通过常量引用传递参数的矩阵模板类
- 在C++中使用非常量引用作为常量
- 具有常量引用参数的函数模板专用化
- 多个"常量引用"变量可以共享同一个内存吗?
- 为什么 STL 容器适配器堆栈中的 top 返回常量引用?
- 为什么常量方法可以采用非常量引用?
- 为什么当我们有常量引用时创建临时对象?
- 如何返回向量的常量引用?
- C++:常量引用参数
- 不同于按值传递和常量引用传递的程序集
- 为什么const_cast和static_cast常量引用没有效果?
- C++ 获取函数在常量引用中按值返回的结果
- 从 BubbleSort* 类型的右值初始化 'AssortedSorter&' 类型的非常量引用无效"
- C++ 在类中使用常量引用文本时 O2 内存泄漏
- 是否可以跨 dll 边界返回常量引用/指向 std::vectors?
- C++中大多数/所有 setter 函数的参数是否应该写为常量引用?
- 通过非常量引用参数修改常量引用参数
- 将常量引用传递给线程
- 为什么C++中没有常量引用,就像常量指针一样?