简体   繁体   中英

Why void_t doesnt work in SFINAE but enable_if does

I was trying to understand how SFINAE works and I was experimenting with this code

#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>();
}

The commented code works but the first doesn't . The compiler gives me errors saying that there is a redefinition and that template argument deduction failed. Could someone explain why this happens? The two void_t s should be independent right? Since one line checks for x and the other for y . How can I fix?

This seems to be related to CWG issue #1980 (credits to TC for correcting me) .

As a workaround you can define void_t as:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM