Hello.
I've recently asked two questions on StackOverflow :
The issue can be depicted with the below snippet:
template <class T>
using identity = T;
template <class T>
using forwarding_reference = T&&;
template <class T>
void foo(T&&) {} // #1
template <class T>
void foo(identity<T>&&) {} // #2
template <class T>
void foo(identity<T&&>) {} // #3
template <class T>
void foo(forwarding_reference<T>) {} // #4
int main()
{
int i{};
foo(i);
}
Functions #2, #3, #4 are all rejected as redefinitions of #1 by both GCC and Clang, as if they were true forwarding references.
In fact, when left alone, GCC 6.0.0 uses type deduction rules for forwarding-references and successfully compiles each one when an lvalue is used as the argument (T is deduced as int&).
For Clang 3.7.0 the situation looks similar, except that for #2 it deduces int, and the parameter type becomes int&& (although it would still reject #2 as a redefinition of #1 !).
The answers on StackOverflow are quite interesting, but differ a lot - three different opinions: "These are not forwarding references", "These could be forwarding references, but it's unspecified", and "I very much believe these are all forwarding references".
Would you help to solve this problem? Is it specified in the Standard?