![](/img/trans.png)
[英]invalid initialization of non-const reference of type ‘std::string&
[英]a reference of type “std::string&” (not const-qualified) cannot be initialized
當我嘗試編譯以下 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]"
您的代碼有兩個問題。 首先, "Hello World!"
是char const[13]
,而不是std::string
。 因此編譯器必須(隱式)將其轉換為std::string
。 轉換的結果是一個臨時的(C++ 中的右值),並且您不能使用臨時初始化對非常量的引用。 第二個是即使你可以(或者你聲明了 function 以返回對 const 的引用),你返回的引用將立即從 Z31A1FD140BE4BEF2D11E121EC9A18A 中取出 go (因此被破壞)5; 對結果引用的任何使用都將導致未定義的行為。
真正的問題是:為什么要引用? 除非您實際上指的是 object 中具有更長生命周期的東西,目的是客戶端代碼修改它(通常不是一個好主意,但有明顯的例外,例如矢量的operator[]
),您應該返回按價值。
“Hello World”不是一個字符串,它是一個字符數組。 c++ 編譯器需要將其轉換為字符串值,而不是字符串引用(因為它不是字符串),因此您的 function 應如下所示:
string foo(){
return "Hello World";
}
要擴展(應 OP 的要求),編譯器會執行以下操作:
string foo(){
char a[] = "Hello World";
string s( a );
return s;
}
值 s 由 std::string 復制構造函數從 function 中復制出來。
您正在指示編譯器返回從 char 數組“Hello World”創建的臨時 std::string。 它需要把它放在某個地方,並有人負責清理它。 您可以通過以下幾種方式做到這一點:
第二個可能是最簡單的。 編譯器將使用 RVO(返回值優化)來刪除由它調用的副本。
就這樣做吧。
const string foo() {
return string("Hello World");
}
我想你想要:
string foo(){
return "Hello World";
}
要了解該問題及其解決方案,您必須了解編譯器的一些工作原理。 但是,別擔心,我會解釋並盡可能保持簡單。
在第一個示例中,我們希望將“引用”返回給已創建的字符串,該字符串應具有 memory 地址(我的意思是左值)。 如果我們返回,像這樣:
string& foo()
{
return "Example String";
}
它永遠不會起作用,因為你可能已經找到了原因。 字符串:“示例字符串”是一個臨時值,沒有 memory 地址,因為它尚未構造。 它必須在任何字符串變量內部的某個地方構造,在那里它將被分配給 memory 地址。 目前,它沒有 memory 地址(我的意思是右值)。
同樣,在第二種情況下,如果我們這樣做:
string foo()
{
return "Example String";
}
在這里,我們實際上是在構造一個 String 類型的新變量,從那里調用它。 例如,如果我們這樣做:
int main()
{
string Test = foo();
}
將在等式運算符的右側創建一個字符串變量,並將數據復制到測試變量(如果禁用編譯器優化)。 但是等等,還有別的東西。
這里有一些編譯器的魔法。 不讓事情變得復雜:),我只想說,它也有string& foo()和string foo()的特性,還有一些額外的特性。
這意味着如果我們這樣做:
const string& foo()
{
string Test = "Example String";
return Test;
}
這會將(常量)“引用”返回到字符串 Test。 這很明顯。 但是,如果我們這樣做:
const string& foo()
{
return "Example String";
}
編譯器將為“示例字符串”智能地創建一個臨時寄存器(在匯編中)並將其存儲在那里。 然后,它將返回對該寄存器的引用。 這個 Register 事情只發生在 const Reference 的情況下。
使用const string& foo()來解決您的問題,您可能知道我們這樣做的原因:)。 如果您想了解更多信息,請查看 C++ 中的類型系統主題。 快樂學習。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.