Sample code (taken from here [uses core issue 2118], slightly modified):
#include <type_traits>
template<int N> struct tag{};
template<typename T, int N>
struct loophole_t
{
friend auto loophole(tag<N>) { return T{}; };
};
auto loophole(tag<0>);
struct detector
{
template <typename T, int = sizeof(loophole_t<T, 0>)>
operator T();
};
template <typename T, int = sizeof(T{detector{}})>
constexpr auto get_type()
{
return loophole(tag<0>{});
}
typedef double T;
struct test
{
T x;
};
int main(void)
{
static_assert( std::is_same<T, decltype(get_type<test>())>::value, "xxx" );
return 0;
}
Invocations:
$ gcc t0.cpp -std=c++14 -pedantic -Wall -Wextra
<nothing>
$ icc t0.cpp -std=c++14 -pedantic -Wall -Wextra
<nothing>
$ clang t0.cpp -std=c++14 -pedantic -Wall -Wextra
<source>:22:12: error: function 'loophole' with deduced return type cannot be used before it is defined
return loophole(tag<0>{});
^
<source>:11:6: note: 'loophole' declared here
auto loophole(tag<0>);
$ cl t0.cpp /std:c++14 /Za
<nothing>
Why doesn't Clang see the function definition? What the standard says?