I'm just playing around with some SFINAE code and I can't get it to work. I'm using Xcode 12.2 with -std=c++17. godbolt reveals that Clang does indeed choose the false_type variant no matter what, whereas gcc uses the true_type variant if both template parameters are identical and the operator is implemented, as I would expect it to. See the code below:
#include <iostream>
#include <type_traits>
struct MyStruct {};
std::ostream& operator<<(std::ostream& os, const MyStruct&) {
return os;
}
template<typename T, typename U = void>
struct has_ostream_operator : std::false_type {};
template<typename T>
struct has_ostream_operator<T, typename std::enable_if_t<sizeof(std::declval<std::ostream&>() << std::declval<T>()), T>> : std::true_type {};
int main() {
constexpr bool res = has_ostream_operator<MyStruct, MyStruct>::value;
if constexpr(res) {
std::cout << "Yes";
} else {
std::cout << "No";
}
return 0;
}
Can someone explain to me what's going on here and why Clang and gcc would behave differently? I've already solved the problem using a different technique, so this is merely for educational purposes :-)