SFINAE`std :: void_t`类模板专门化

Bia*_*sta 7 c++ templates sfinae c++17 void-t

使用SFINAE,我需要检测容器的某些属性。

例如:

#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);
Run Code Online (Sandbox Code Playgroud)

上面的代码可以按预期进行编译和运行(在clanggcc上)。在这里检查

但是,如果我稍加修改将模板类型包装在里面的代码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;
};
Run Code Online (Sandbox Code Playgroud)

然后,它可以在gcc上工作并编译,但是在clang上被拒绝。在这里检查

特别是,埋怨redifinitionTrait


问题(关于第二版代码):

1)这是一个叮当响的 bug吗?

2)如果clang是标准投诉(例如,它是gcc错误),为什么添加std::void_t会重新定义Trait?我希望SFINAE会阻止重新定义。