http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51547
Bug #: 51547 Summary: auto, type deduction, reference collapsing and const: invalid initialization of reference of type 'const X&&' from expression of type 'const X' Classification: Unclassified Product: gcc Version: 4.6.2 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: tud...@fb.com Created attachment 26074 --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=26074 g++ -E output The following program fails to compile using g++ 4.6.2 (g++ -std=c++0x) #include <vector> struct Bar { int x; }; struct Foo { const std::vector<Bar>& bar() const { return bar_; } std::vector<Bar> bar_; }; template <class X> struct Y { void foo() { Foo a; auto b = a.bar().begin(); auto&& c = b->x; } }; template <class X> void foo() { Foo a; auto b = a.bar().begin(); auto&& c = b->x; } int main() { Y<int> p; p.foo(); foo<int>(); } a.cpp: In member function ‘void Y<X>::foo() [with X = int]’: a.cpp:34:9: instantiated from here a.cpp:20:19: error: invalid initialization of reference of type ‘const int&&’ from expression of type ‘const int’ a.cpp: In function ‘void foo() [with X = int]’: a.cpp:35:12: instantiated from here a.cpp:28:17: error: invalid initialization of reference of type ‘const int&&’ from expression of type ‘const int’ The program compiles correctly if Y or foo() are non-templates. Reference collapsing should deduce "auto&& c" as "const int&", and it appears to do so in the non-template case. Note that this bug is very brittle to reproduce (I tried to reduce it to remove the use of std::vector, but I couldn't) -- for example, replacing "b->x" with "(*b).x" makes the code compile correctly. Attaching the preprocessor output (g++ -std=c++0x -E)