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.

Другие вопросы по тегам