2013-05-01 44 views
8

鑑於這些2個函數修改,並返回一個字符串:使用GCC G ++什麼保證重載的非const方法被調用?

// modify the original string, and for convenience return a reference to it 
std::string &modify(std::string &str) 
{ 
    // ...do something here to modify the string... 
    return str; 
} 

// make a copy of the string before modifying it 
std::string modify(const std::string &str) 
{ 
    std::string s(str); 
    return modify(s); // could this not call the "const" version again? 
} 

此代碼對我的作品,但我不明白爲什麼/如何。我擔心第二個函數會自動調用,讓我失控遞歸,直到堆棧耗盡。這是保證工作嗎?

+0

這是最有可能的尾遞歸。我不確定將const-ref調用轉換爲循環的語義,因此不會發布答案,而是查看尾遞歸,並且可以找到更多信息。 – ssube 2013-05-01 19:42:21

+2

@peachykeen:不,它根本不是遞歸的。 – 2013-05-01 19:44:14

+0

考慮選擇一個更好地關注問題的標題 - 例如「什麼保證重載的非const方法被調用?」 – user2246674 2013-05-01 19:48:20

回答

9

你有兩個重載函數:

std::string &modify(std::string &str) 
std::string modify(const std::string &str) 

什麼你傳遞一個非const限定std::string。因此,採用非常量限定參數的函數更適合。如果不存在,編譯器可能會將非const限定字符串轉換爲const限定字符串以進行調用,但對於函數重載不需要轉換的調用而言,要比需要調用轉換。

3
return modify(s); // could this not call the "const" version again? 

號是遞歸。它會調用其他過載參數爲std::string &

這是因爲表達式s的類型是std::string &,它與其他重載函數的參數類型相匹配。

爲了緩解,呼叫站點的參數需要轉換爲std::string const &。但在你的情況下,這種轉換是不必要的,因爲存在不需要轉換的過載。

1

這不是遞歸,它是超載。當你調用第二個函數時,進入它的參數是一個常量字符串。在該函數內部,您可以調用另一個採用非常量字符串的函數。你正在做的是剝離字符串的常量,更好的方法是使用const_cast。

I'll just link to this other stackoverflow thread.

+0

我不想刪除常量。這將導致一個看起來常量字符串被修改! – 2013-05-01 19:55:22

+0

你可以做的是通過做一些事情來分配非常量字符串:std :: string&str2 = const_cast (str)。 str將保持不變,但您可以根據需要修改str2。 – Shaz 2013-05-01 20:04:48

相關問題