GCC 4.7.2不不指定的標誌-std=c++98
是當編譯此。事實上,在C++ 98(以及C++ 03)中,對引用的引用不會崩潰。
試圖實例f<int&>
,其中T = int&
,產生以下函數簽名(這裏我故意切換參數類型T
和const
說明符,這是允許的,因爲const T&
的位置是一樣的T const&
):
void f(int& const& t) // ERROR: reference to reference is illegal
上述內容在C++ 98和C++ 03中都不合法。一致的是,這是你從GCC 4.7.2得到錯誤:
Compilation finished with errors:
source.cpp: In function 'int main()':
source.cpp:15:14: error: no matching function for call to 'f(int&)'
source.cpp:15:14: note: candidate is:
source.cpp:5:6: note: template<class T> void f(const T&)
source.cpp:5:6: note: template argument deduction/substitution failed:
source.cpp: In substitution of 'template<class T> void f(const T&) [with T = int&]':
source.cpp:15:14: required from here
source.cpp:5:6: error: forming reference to reference type 'int&'
不過,如果你使用-std=c++11
標誌,則編譯器執行基準實例化模板時崩潰:左值引用一個左參考變成左值參考:
void f(int& const& t) == void f(int& t)
這裏const
預選賽被放棄了,因爲它適用於參考,而不是引用的對象。由於引用不能被重新分配,它們本質上是const
,這就是爲什麼const
被認爲是多餘的並被刪除的原因。有關說明,請參閱this Q&A on SO。
這產生一個左值引用的左值引用,它將解析爲一個簡單的左值引用。因此,右側的簽名被實例化。
以上是解決f<int&>(a)
問題的可行方案,因此編譯時無誤。
我無法在C++ 98或C++ 03中找到該報價。 §14.3.1是「模板類型參數」,沒有小節或第4段。 –