GCC 4.7.2 không không biên dịch này khi lá cờ -std=c++98
được chỉ định. Trong thực tế, trong C++ 98 (cũng như trong C++ 03) tham chiếu đến tham chiếu không sụp đổ.
Một cố gắng để nhanh chóng f<int&>
, nơi T = int&
, tạo ra chức năng chữ ký sau đây (ở đây tôi cố tình chuyển đổi vị trí của các loại lập luận T
và const
specifier, được cho phép bởi vì const T&
cũng giống như T const&
):
void f(int& const& t) // ERROR: reference to reference is illegal
Ở trên không hợp pháp trong C++ 98, cũng như trong C++ 03. Liên tục, đây là lỗi mà bạn nhận được từ 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&'
Tuy nhiên, nếu bạn sử dụng -std=c++11
cờ, sau đó trình biên dịch thực hiện tham khảo sụp đổ khi instantiating mẫu: một tài liệu tham khảo giá trị trái với một tài liệu tham khảo giá trị trái trở thành một tham khảo giá trị trái:
void f(int& const& t) == void f(int& t)
Ở đây const
vòng loại được giảm xuống, vì nó áp dụng cho các tài liệu tham khảo, và không để các đối tượng được tham chiếu. Vì tham chiếu không thể được gán lại, chúng tự nhiên là const
, đó là lý do tại sao số const
được coi là thừa và bị loại bỏ. Xem this Q&A on SO để được giải thích.
Điều đó mang lại tham chiếu giá trị lvalue cho tham chiếu giá trị lvalue, giải quyết thành tham chiếu lvalue đơn giản. Do đó, chữ ký ở bên phải được khởi tạo.
Ở trên là một ứng cử viên khả thi để giải quyết cuộc gọi cho f<int&>(a)
và do đó, nó biên dịch mà không có lỗi.
Tôi không thể tìm thấy trích dẫn đó bằng C++ 98 hoặc C++ 03. §14.3.1 là "đối số kiểu mẫu" và không có tiểu mục hoặc đoạn 4. –