https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68388
Bug ID: 68388 Summary: incomplete type bug when using decltype Product: gcc Version: 6.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: ryan.burn at gmail dot com Target Milestone: --- The below code compiles fine with clang (http://melpon.org/wandbox/permlink/Rm6dpbmC0N3eMJJa) and earlier versions of gcc-6, but was recently broken. Gcc gives this error when compiling: bug.cpp: In instantiation of ‘auto map_impl(std::index_sequence<Indexes ...>, Functor, T1, T2) [with int ...Indexes = {0}; Functor = Less; T1 = Tuple<int>; T2 = Tuple<int>]’: bug.cpp:27:11: required from ‘auto map_impl(Functor, T1, T2) [with Functor = Less; T1 = Tuple<int>; T2 = Tuple<int>]’ bug.cpp:40:26: required from here bug.cpp:22:3: error: invalid use of incomplete type ‘class Tuple<decltype (apply_impl<Indexes>(f, t1, t2))...>’ Tuple<decltype(apply_impl<Indexes>(f, t1, t2))...>(); ^~~~~ bug.cpp:8:27: note: declaration of ‘class Tuple<decltype (apply_impl<Indexes>(f, t1, t2))...>’ template <class...> class Tuple {}; /////////////////////////////////////////////////////////// typedef int size_t; template <std::size_t... Indexes> struct index_sequence {}; } template <class...> class Tuple {}; template <std::size_t I, class TFirst> auto get(Tuple<TFirst>) { return TFirst(); } template <std::size_t I, class Functor, class T1, class T2> auto apply_impl(Functor f, T1 t1, T2 t2) { return f(get<I>(t1), get<I>(t2)); } template <std::size_t... Indexes, class Functor, class T1, class T2> auto map_impl(std::index_sequence<Indexes...>, Functor f, T1 t1, T2 t2) { Tuple<decltype(apply_impl<Indexes>(f, t1, t2))...>(); } template <class Functor, class T1, class T2> auto map_impl(Functor f, T1 t1, T2 t2) { map_impl(std::index_sequence<0>(), f, t1, t2); } struct Less { template <class Lhs, class Rhs> auto operator()(Lhs lhs, Rhs rhs) -> decltype(lhs < rhs) { return lhs < rhs; } }; int main() { auto t1 = Tuple<int>(); auto t2 = Tuple<int>(); map_impl(Less(), t1, t2); } ///////////////////////////////////////////////////////////