https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86480
Bug ID: 86480 Summary: [8 Regression] error: parameter packs not expanded with '...' in a recursive variadic lambda Product: gcc Version: 8.1.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: gufideg at gmail dot com Target Milestone: --- The following code compiler with Clang and GCC 7.3: #include <type_traits> #include <functional> #include <tuple> template<typename Tuple, typename = std::make_index_sequence<std::tuple_size_v<Tuple>>> struct tuple_sequence_helper; template<typename T, typename I, I... S> struct tuple_sequence_helper<T, std::integer_sequence<I, S...>> { using type = std::tuple<std::integral_constant<I, S>...>; }; template<auto N, typename F> constexpr auto apply_sequence(F function) -> decltype(auto) { return std::apply(function, typename tuple_sequence_helper<void, std::make_integer_sequence<decltype(N), N>>::type{}); } template<typename, typename> struct drop_last_helper; template<typename T, std::size_t... S> struct drop_last_helper<T, std::index_sequence<S...>> { using type = std::tuple<std::tuple_element_t<S, T>...>; }; template<typename> struct drop_last; template<typename... Args> struct drop_last<std::tuple<Args...>> : drop_last_helper<std::tuple<Args...>, std::make_index_sequence<sizeof...(Args) - 1>> {}; template<typename T> using drop_last_t = typename drop_last<T>::type; template<typename, typename Tup, typename, typename = void> struct dropping_invoke_result_helper {}; template<typename F, typename... Args, typename T> struct dropping_invoke_result_helper<F, std::tuple<Args...>, T, std::enable_if_t<std::is_invocable_v<F, Args...>>> { using type = std::invoke_result_t<F, Args...>; }; template<typename F, typename H, typename... T, std::size_t... S> struct dropping_invoke_result_helper<F, std::tuple<H, T...>, std::index_sequence<0, S...>, std::enable_if_t<!std::is_invocable_v<F, H, T...>>> : dropping_invoke_result_helper<F, std::tuple<std::tuple_element_t<S - 1, std::tuple<H, T...>>...>, std::make_index_sequence<sizeof...(S)>> {}; template<typename F, typename... Args> using dropping_invoke_result = dropping_invoke_result_helper<F, std::tuple<Args...>, std::index_sequence_for<Args...>>; template<typename F, typename... Args> using dropping_invoke_result_t = typename dropping_invoke_result<F, Args...>::type; template<typename F, typename... Args> auto dropping_invoke(F&& f, Args&&... args) -> dropping_invoke_result_t<F, Args...> { auto recurse = [](auto self) { return [self](auto&&... as) -> decltype(auto) { return self(self, std::forward<decltype(as)>(as)...); }; }; auto drop = recurse([&f](auto self, auto&&... as) -> dropping_invoke_result_t<F, Args...> { return apply_sequence<sizeof...(as) - 1>([&f, &as..., &self](auto... s) -> decltype(auto) { auto pack = std::forward_as_tuple(std::forward<decltype(as)>(as)...); if constexpr (std::is_invocable_v<F, std::tuple_element_t<s, decltype(pack)>...>) { return std::invoke( std::forward<F>(f), std::forward<std::tuple_element_t<s, decltype(pack)>>(std::get<s>(std::move(pack)))... ); } else { return self(self, std::forward<F>(f), std::forward<std::tuple_element_t<s, decltype(pack)>>(std::get<s>(std::move(pack)))...); } }); }); return drop(drop, std::forward<Args>(args)...); } int main() { dropping_invoke( [](auto a, int b){}, 42.f, 12, 23 ); } I have not succeeded to reduce it more, sorry for the large repro.