2011-05-25 261 views
3

當我嘗試編譯以下函數時,出現錯誤。類型「std :: string&」(不是const限定的)的引用無法初始化

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

歡迎來到Stack Overflow。這是一個問答網站,您在其中提出問題,其他人則提供答案。但是你的帖子沒有問題!請編輯您的帖子以包含問題。 – 2011-05-25 15:47:48

+1

你爲什麼要那樣做? – 2011-05-25 15:48:04

+2

我想看起來像一個居高臨下的白癡!顯然你知道他在尋求幫助。 – MJLaukala 2014-09-21 02:25:54

回答

20

您的代碼有兩個問題。首先,"Hello World!"char const[13],而不是std::string。所以編譯器必須 (隱式)將其轉換爲std::string。 轉換的結果是臨時的(在C++中是右值 - 說),並且不能用 初始化對具有臨時值的非const的引用。第二個是 ,即使你可以(或者你宣佈函數返回一個對const的 引用),你也會返回一個引用,它將立即超出範圍(因此被破壞)。任何使用 的結果引用都將導致未定義的行爲。

真正的問題是:爲什麼參考?除非你實際上是指 指的是具有較長生命週期的對象中的東西,而 意圖是客戶端代碼修改它(通常不是一個好主意,但 有明顯的例外,如operator[]的一個向量),您應該按價值返回 。

+2

+1。最好的解釋最好的答案。 – Nawaz 2011-05-25 17:02:11

10

「Hello World」不是一個字符串,它是一個char數組。 C++編譯器需要將它轉換成一個字符串值,不是字符串引用(因爲它不是一個字符串),所以你的函數應該是這樣的:

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

擴大(在OP的要求)編譯器做一些事情像這樣:

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

通過std :: string拷貝構造函數將s拷貝出函數。

+0

所以這將通過值傳遞和字符串將被複制到接收變量。當你創建char數組並且創建字符串對象的時候,你也可以分享一下。是否這樣,編譯器首先創建char數組,當它看到該類型是字符串時,它會將其轉換爲字符串。對不起,如果這聽起來很荒唐。我是一個非常困惑的初學者。 – wayfare 2011-05-25 16:00:18

2

您正在指示編譯器返回從char數組「Hello World」創建的臨時std :: string。它需要把它放在某個地方,並有人負責清理它。你可以做到這一點在幾個方面:

  • 返回一個auto_ptr
  • 返回一個字符串對象
  • 返回一個常量引用一個字符串對象(雖然這並不讓我與誰清除它的問題? )
  • (僅限C++ 0x)返回std :: string的右側引用。 (std :: string & &)

第二個可能是最簡單的。編譯器將使用RVO(返回值優化)來刪除由其調用的副本。

-1

我想你想:

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

我們已經通過了這個。它失敗的原因是因爲它在使用中表現出未定義的行爲。請刪除此答案。 – 2011-05-25 16:54:49

+0

我編輯了我的答案。 – user757421 2011-05-25 17:09:09

+0

@all:我不明白爲什麼這應該被刪除。 – 2011-06-20 18:47:06

0

只是這樣做。

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

他爲什麼要這麼做? – 2011-05-25 17:34:40

相關問題