为什么 void_t 在 SFINAE 中不起作用,但 enable_if 却起作用

Why void_t doesnt work in SFINAE but enable_if does

我试图了解 SFINAE 的工作原理并且我正在试验这段代码

#include <type_traits>

struct One { 
  using x = int; 
};
struct Two { 
  using y = int; 
};

template <typename T, std::void_t<typename T::x>* = nullptr>
void func() {}
template <typename T, std::void_t<typename T::y>* = nullptr>
void func() {}

/*template <typename T, std::enable_if_t<std::is_same_v<typename T::x, typename T::x>>* = nullptr>
void func() {}
template <typename T, std::enable_if_t<std::is_same_v<typename T::y, typename T::y>>* = nullptr>
void func() {} */



int main() {
  func<One>();
  func<Two>();
}

注释的代码有效,但第一个无效。编译器给我错误说有一个重新定义并且模板参数推导失败。有人可以解释为什么会这样吗?两个 void_t 应该是独立的吧?因为一行检查 x 而另一行检查 y。我该如何解决?

这似乎与CWG issue #1980 (credits to T.C.有关,请指正)

作为解决方法,您可以将 void_t 定义为:

template<typename... Ts> struct make_void { typedef void type;};
template<typename... Ts> using void_t = typename make_void<Ts...>::type;

(from cppreference)

live example on wandbox