https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108414
--- Comment #3 from Jonathan Wakely <redi at gcc dot gnu.org> --- Reduced: using size_t = decltype(sizeof(0)); template<typename T> struct type_identity { using type = T; }; template<typename T, typename U> constexpr bool is_same_v = false; template<typename T> constexpr bool is_same_v<T, T> = true; template<typename... Ts> struct type_list {}; template <size_t I, typename T> struct indexed { using type = T; }; template <size_t I, typename ...Ts> struct indexer; template <size_t I, typename T, typename ...Ts> struct indexer<I, T, Ts...> : indexed<I, T>, indexer<I+1, Ts...> {}; template <size_t I, typename T> struct indexer<I, T> : indexed<I, T> {}; template <size_t I, typename ...Ts> using nth_element_t = typename decltype([]<typename T>(const indexed<I, T>&){return type_identity<T>{};}(indexer<0, Ts...>{}))::type; template<size_t I, typename T> struct nth_type; template<size_t I, typename ... Ts> struct nth_type< I, type_list<Ts...> > { #ifndef USING typedef nth_element_t<I, Ts...> type; // Incorrect result with it #else using type = nth_element_t<I, Ts...>; // Compile error #endif }; template<size_t I, typename T> using nth_type_t = typename nth_type<I, T>::type; using list = type_list<int, float, double>; using elm0 = nth_type_t<0, list>; using elm1 = nth_type_t<1, list>; using elm2 = nth_type_t<2, list>; static_assert( is_same_v<elm0, int> ); static_assert( is_same_v<elm1, float> ); static_assert( is_same_v<elm2, double> ); Without -DUSING nth.cc:47:16: error: static assertion failed 47 | static_assert( is_same_v<elm1, float> ); | ^~~~~~~~~~~~~~~~~~~~~~ nth.cc:48:16: error: static assertion failed 48 | static_assert( is_same_v<elm2, double> ); | ^~~~~~~~~~~~~~~~~~~~~~~ With -DUSING nth.cc: In substitution of 'template<long unsigned int I, class T> using nth_type_t = typename nth_type::type [with long unsigned int I = 0; T = type_list<int, float, double>]': nth.cc:42:32: required from here nth.cc:38:7: error: no type named 'type' in 'struct nth_type<0, type_list<int, float, double> >' 38 | using nth_type_t = typename nth_type<I, T>::type; | ^~~~~~~~~~ nth.cc: In substitution of 'template<long unsigned int I, class T> using nth_type_t = typename nth_type::type [with long unsigned int I = 1; T = type_list<int, float, double>]': nth.cc:43:32: required from here nth.cc:38:7: error: no type named 'type' in 'struct nth_type<1, type_list<int, float, double> >' nth.cc: In substitution of 'template<long unsigned int I, class T> using nth_type_t = typename nth_type::type [with long unsigned int I = 2; T = type_list<int, float, double>]': nth.cc:44:32: required from here nth.cc:38:7: error: no type named 'type' in 'struct nth_type<2, type_list<int, float, double> >' nth.cc:46:26: error: 'elm0' was not declared in this scope 46 | static_assert( is_same_v<elm0, int> ); | ^~~~ nth.cc:46:16: error: template argument 1 is invalid 46 | static_assert( is_same_v<elm0, int> ); | ^~~~~~~~~~~~~~~~~~~~ nth.cc:47:26: error: 'elm1' was not declared in this scope 47 | static_assert( is_same_v<elm1, float> ); | ^~~~ nth.cc:47:16: error: template argument 1 is invalid 47 | static_assert( is_same_v<elm1, float> ); | ^~~~~~~~~~~~~~~~~~~~~~ nth.cc:48:26: error: 'elm2' was not declared in this scope 48 | static_assert( is_same_v<elm2, double> ); | ^~~~ nth.cc:48:16: error: template argument 1 is invalid 48 | static_assert( is_same_v<elm2, double> ); | ^~~~~~~~~~~~~~~~~~~~~~~