The following invalid program is accepted by gcc and msvc but rejected by clang. ``` #include <utility> #include <iostream> template< class T > void f( T& t ){} ; template< class T > void f( const T&& ) {}; int main() { int i = 0; f<int&>(i); //clang:nope, gcc:ok, msvc:ok } ``` Demo: https://godbolt.org/z/4K7ErvWjh Related thread: https://stackoverflow.com/questions/79034394/function-template-overloading-when-called-with-reference-type-rejected-by-clang
EDG also accepts it. So maybe this is a clang issue.
https://developercommunity.visualstudio.com/t/MSVC-accepts-invalid-call-to-overloaded/10755162
EDG, GCC and MSVC all use the reference function rather const rvalue reference function. if we change the const rvalue reference to just an rvalue reference, then clang accepts it: > template< class T > void f( T&& ) { puts("rvalue-reference"); }; So are you sure this is not a clang issue?
> So are you sure this is not a clang issue? Yes, because [temp.deduct.partial#9.1] make the second overload not to be atleast as specialized as the first and then [temp.deduct.partial#9.2] make the first template not to be atleast as specialized as the second. So neither overloads are at least as specialized than the other and hence also **neither of them more specialized**. This was explained in the thread link I posted in the original bug: https://stackoverflow.com/a/79034540/12002570 Now coming to the example you gave where we have changed the second overload to `f(T&&)`, this starts working because then the [temp.deduct.partial#9.2] will no longer apply and we will get on of the overloads more specialized than the other.
That [temp.deduct.partial] wording was changed with wg21.link/cwg1705. It seems GCC is behaving correctly wrt to the old wording and just hasn't implemented the new wording?