https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66042
Bug ID: 66042 Summary: Implicitly converts lvalue to rvalue when returning reference parameter in function template Product: gcc Version: 5.1.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: david at doublewise dot net Target Milestone: --- #include <type_traits> template<typename T> auto compiles(T && t) -> T && { static_assert(std::is_same<T, int>::value, "Incorrect type deduced for T."); return t; } static_assert(std::is_same<int &&, decltype(compiles(0))>::value, "shouldn't compile"); auto fails(int && t) -> int && { return t; } static_assert(std::is_same<int &&, decltype(fails(0))>::value, "doesn't compile"); Neither function should compile. In the function template case, T is deduced as int, so the parameter type is int &&. Local variables and function parameters taken by value can be implicitly moved into the return value, but not function parameters taken by rvalue reference (t is an lvalue, even though decltype(t) == int &&). The non-template function correctly honors this behavior. If the return type of compiles is changed to decltype(auto) or auto &&, then the function correctly returns int & and the static_assert fires.