Using SFINAE, I need to detect some properties of a container.
For example:
#include <type_traits>
#include <vector>
template <typename Container, typename = void>
struct Trait {};
template <typename Container>
struct Trait<
    Container,
    std::enable_if_t<std::is_integral_v<typename Container::value_type>>> {
  static constexpr bool foo = false;
};
template <typename Container>
struct Trait<
     Container, 
     std::enable_if_t<std::is_floating_point_v<typename Container::value_type>>> {
  static constexpr bool foo = true;
};
static_assert(Trait<std::vector<int>>::foo == false);
static_assert(Trait<std::vector<double>>::foo == true);
The above code compiles and works as expected (both on clang and gcc). Check here.
However, if I slightly modify the code wrapping the template type inside a std::void_t:
template <typename Container>
struct Trait<
    Container,
    std::void_t<std::enable_if_t<std::is_integral_v<typename Container::value_type>>>> {
  static constexpr bool foo = false;
};
template <typename Container>
struct Trait<
    Container, 
    std::void_t<std::enable_if_t<std::is_floating_point_v<typename Container::value_type>>>> {
  static constexpr bool foo = true;
};
then, it works and compiles on gcc but it is rejected on clang. Check here.
In particular, clang complains about the redifinition of Trait.
Questions (about the second version of code):
1) Is this a clang bug?
2) In case clang is standard complaint (i.e., it is a gcc bug), why adding std::void_t creates a redefinition of Trait? I expect that SFINAE would prevent the redifinition.