void_t в списке параметров работает, но не как тип возвращаемого значения
На cppreference есть пример использования псевдонима. Этот пример терпит неудачу, потому что int
не имеет члена foo
:
template<typename...> using void_t = void;
template<typename T> void_t<typename T::foo> f();
f<int>(); // error, int does not have a nested type foo
Это понятно, но когда я попытался положить void_t
часть в списке параметров он неожиданно скомпилировал:
template<typename...> using void_t = void;
template<typename T> void f(void_t<typename T::foo>);
f<int>();
Он компилируется в Clang, но не в GCC. Это ошибка?
1 ответ
Решение
template<class...>struct voider{using type=void;};
template<class...Ts>using void_t=typename voider<Ts...>::type;
В стандарте C++11 существует неоднозначность того, являются ли неиспользуемые параметры шаблона для шаблона с использованием псевдонимов, которые являются недопустимыми типами / выражениями, ошибкой замещения или нет.
gcc и clang по-разному истолковали это предложение, что, я думаю, вы видите. Выше void_t
должен заставить его работать одинаково как в gcc, так и в clang.