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

时间:2017-06-30 11:57:41

标签: c++ c++17 sfinae

我试图理解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。我该如何解决?

1 个答案:

答案 0 :(得分:13)

这似乎与CWG issue #1980 相关(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