This question is related to this answer.
In this example SFINAE uses variable template has_literal_x
specialization instead of the base template:
struct A { };
A operator"" _x(char const*) { return {}; }
template<typename T, typename S, typename = void>
constexpr bool has_literal_x = false;
template<typename T, typename S>
constexpr bool has_literal_x<T, S,
std::enable_if_t<
std::is_same<
decltype(operator""_x(std::declval<S>())), T
>::value
>
> = true;
int main()
{
std::cout << has_literal_x<A, char const*> << std::endl; // 1
}
And here it uses the base template:
template<typename T, typename S, typename = void>
constexpr bool has_literal_x = false;
template<typename T, typename S>
constexpr bool has_literal_x<T, S,
std::enable_if_t<
std::is_same<
decltype(operator""_x(std::declval<S>())), T
>::value
>
> = true;
struct A { };
A operator"" _x(char const*) { return {}; }
int main()
{
std::cout << has_literal_x<A, char const*> << std::endl; // 0
}
On both GCC (first, second) and Clang (first, second) order of defining templates and user literal changes which overload is chosen by SFINAE. Why?