http://herbsutter.com/2008/01/01/gotw-88-a-candidate-for-the-most-important-const/它提到了「最重要的const」,C++故意指定將臨時對象綁定到堆棧上的const引用將臨時的生命週期延長到引用本身的生命週期。我想知道爲什麼C++只允許當引用是const時延長對象的生命週期而不是當它不是時?該功能背後的理性是什麼?爲什麼它必須是const?爲什麼「最重要的const」必須是const?
回答
考慮以下情況:如果這被允許
int& x = 5;
x = 6;
應該發生什麼?相比之下,如果你做
const int& x = 5;
將沒有合法的方式來修改x
。
應該創建一個值爲5的隱藏本地變量。沒有技術原因不允許。 –
@NeilKirk然而,這並不是你期待的'int&',它只是編譯器設計者的一個負擔,並且與int x = 5沒有區別。 –
@tohecz但這是如何使用來自正常函數的返回值實現const ref綁定。所有功能對於編譯器設計人員來說都是「負擔」,這並不是它成爲功能的原因! – dan
下面是一個例子:
void square(int &x)
{
x = x * x;
}
int main()
{
float f = 3.0f;
square(f);
std::cout << f << '\n';
}
如果臨時變量可以結合非const左值引用,上述將愉快地編譯,但產生相當令人吃驚的結果(的3
而不是9
輸出)。
有趣的是,我沒有想到這一點。 –
爲什麼會輸出3? – 0x499602D2
我認爲這是通常的解釋。如果在複製樣式初始化中允許它,但在參數初始化中不允許呢?已經有顯式轉換和隱式轉換。 –
請注意,const引用可以綁定到甚至沒有正常地址的對象。 A const int &
函數參數可以採用由文字常量表達式42
組成的參數。我們不能接受42
的地址,所以我們不能將它傳遞給需要const int *
的函數。
爲了能夠綁定到像這樣的右值,const引用特別「有福」。
當然,對於像2 + 2
這樣的傳統rvalues來說,生存期並不是問題。這是類類型的右值的一個問題。
如果參考的結合被允許一些對象,不像42
,不具有普遍的壽命,即壽命具有被擴展,使得參考在其整個範圍清醒。
這不是說const會導致生命期延長,而是不允許非const引用。如果允許的話,還需要終生延期;在允許某些參考資料在其範圍的某些部分變壞方面沒有意義。這種行爲破壞了參考比指針更安全的概念。
- 1. 爲什麼要使用const T&而不是const T或T&
- 2. const func(const scalar&a)const中的三個「const」,爲什麼?
- 3. 運算符+ =重載,爲什麼是const?
- 4. 是否必須在聲明char const * ptr =「some characters」時使用'const'?
- 5. 什麼是const關鍵字必需
- 6. 爲什麼在引用文字時必須使用const引用
- 7. 「int * const const * b」是什麼意思?
- 8. 什麼是char * const *?
- 9. 爲什麼const int比const int&更快?
- 10. 爲什麼有const和非const訪問?
- 11. 爲什麼const類成員必須是靜態的才能正確優化?
- 12. 爲什麼在一個類中需要const函數和非const?
- 13. 運算符在這裏重載是什麼:String8 :: operator const char *()const
- 14. 爲什麼const char * foo =「Hello」;編譯但不是const int * foo = 5;?
- 15. 爲什麼編譯器選擇const方法而不是非const?
- 16. 爲什麼std :: runtime_error :: what()返回const char *而不是std :: string const&
- 17. 爲什麼boost的counting_iterator是const?
- 18. 爲什麼strlen的參數是「const」?
- 19. C++爲const char *爲const char * const的
- 20. 什麼是const變量?
- 21. 「const類」是什麼意思?
- 22. 什麼是const TAB =^I pascal?
- 23. const是什麼意思?
- 24. 什麼是char * const argv []?
- 25. 轉const const wchar_t *爲const char *
- 26. 爲什麼const有意義?
- 27. 寬鬆擲符爲 '虛擬爲const char * ro_err :: STDERR ::什麼()const的'
- 28. 爲什麼你必須在ES2015中指定導出的類型(let,var,const ...)?
- 29. 爲什麼一個const必須在打字稿的導出類之外?
- 30. 爲什麼這個迭代器是const?
我希望在這裏引用標準,因爲我從來沒有能夠完全說服自己,它*確實需要'const'。 (在N3936中查看12.2 p4和5)。 – BoBTFish
以便編譯器不必在對象超出範圍之前驗證沒有路徑修改臨時文件。 –
@BoBTFish:您正在查看綁定到引用的臨時對象的生命週期。有關如何綁定它們的規則,請參閱[dcl.init.ref](C++ 11中的8.5.3)。特別是,p5的最後一個項目符號:「該引用應該是對非易失性** const **類型[或]右值引用的左值引用。」 –