https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63506
Bug ID: 63506 Summary: GCC deduces wrong return type of operator*() inside template functions Product: gcc Version: 4.9.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: steffen.muething at iwr dot uni-heidelberg.de Created attachment 33681 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=33681&action=edit Minimal working example based on std::vector<bool> When trying to convert some iterators in our numerics library DUNE (dune-project.org) to return temporaries instead of const refs, I stumbled over the following bug in GCC 4.8.3 and 4.9.1: Given a class with an operator*() that returns a temporary: struct iterator { ... proxy operator*() const { return ...; } proxy get() const { return ...; } }; the expression 'decltype(*it())' should yield 'proxy', and a variable declared with 'auto&& x = *it;' should be of type 'proxy&&'. The above is true inside normal functions: void bar(iterator it) { typedef decltype(*it()) P; // P == proxy auto&& x = *it; // decltype(x) == proxy&& } But inside a function template, 'decltype(*it())' becomes 'proxy&', and 'auto&& x = *it' fails with a compiler error: template<typename T> void foo(T t, iterator it) { typedef decltype(*it()) P; // P == proxy& auto&& x = *it; // compiler error, see below } error: invalid initialization of non-const reference of type 'proxy&' from an rvalue of type 'proxy' For some reason, the compiler deduces the wrong type early on and then fails when it later realizes the correct return type... This problem can easily be observed with a std::vector<bool>, which returns a proxy from its iterator. I have attached a minimal working example: The contained code (which creates a vector and iterates over its contents with a range-based for loop using auto&&) works in main() and in a normal function bar(), but it fails to compile in foo(), which is a function template. GCC 4.6 and 4.7 compile foo() correctly.