Подтвердить что ты не робот

Почему void_t не работает в SFINAE, но enable_if делает

Я пытался понять, как работает 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. Как я могу исправить?

4b9b3361

Ответ 1

Это похоже на CWG issue # 1980 (кредиты TC для исправления меня).

В качестве обходного пути вы можете определить void_t как:

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

(из cppreference)

живой пример в wandbox