Почему 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
. Как я могу исправить?
Ответы
Ответ 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