https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96815
Jonathan Wakely <redi at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Keywords| |ice-on-invalid-code Last reconfirmed| |2020-08-27 Ever confirmed|0 |1 Status|UNCONFIRMED |NEW --- Comment #1 from Jonathan Wakely <redi at gcc dot gnu.org> --- #include <iostream> #include <string> #include <variant> #include <tuple> template<typename T> struct A { // evtHandler using type = T; void doStuff(T thing) { std::cout << "nice T ! " << thing << std::endl; } }; template<typename ...args> struct B { // module std::tuple<args...> As; B(args... _As) : As{std::make_tuple(_As...)}{}; template<typename K> void dispatch(K coolObject) { // doStuff for As that match std::apply([&](auto& ... a) { ([&]{if constexpr(std::is_same_v<typename decltype(a)::type, K>) { a.doStuff(coolObject); }}(), ...); }, As); } }; template<typename ...bees> struct C { // controller std::tuple<bees...> Bs; C(bees... _Bs) : Bs{_Bs...} {}; template<typename L> void fullDispatch(L veryCoolObject) { // doStuff for all Bs that match std::apply([&](auto& ... b) { (b.dispatch(veryCoolObject), ...); }, Bs); } }; int main() { auto b1 = B{A<int>{}, A<float>{}, A<double>{}}; auto b2 = B{A<double>{}, A<char>{}, A<bool>{}}; auto c = C{b1, b2}; c.fullDispatch(12.5); } ICEs with -std=gnu++17 96815.C: In instantiation of 'B<args>::dispatch<double>::<lambda(auto:22& ...)> [with auto:22 = {A<int>, A<float>, A<double>}]': /home/jwakely/gcc/10/include/c++/10.2.1/type_traits:2506:26: required by substitution of 'template<class _Fn, class ... _Args> static std::__result_of_success<decltype (declval<_Fn>()((declval<_Args>)()...)), std::__invoke_other> std::__result_of_other_impl::_S_test(int) [with _Fn = B<args>::dispatch<double>::<lambda(auto:22& ...)>; _Args = {A<int>&, A<float>&, A<double>&}]' /home/jwakely/gcc/10/include/c++/10.2.1/type_traits:2517:55: required from 'struct std::__result_of_impl<false, false, B<args>::dispatch<double>::<lambda(auto:22& ...)>, A<int>&, A<float>&, A<double>&>' /home/jwakely/gcc/10/include/c++/10.2.1/type_traits:2522:12: required from 'struct std::__invoke_result<B<args>::dispatch<double>::<lambda(auto:22& ...)>, A<int>&, A<float>&, A<double>&>' /home/jwakely/gcc/10/include/c++/10.2.1/type_traits:138:12: required from 'struct std::__and_<std::__is_invocable_impl<std::__invoke_result<B<args>::dispatch<double>::<lambda(auto:22& ...)>, A<int>&, A<float>&, A<double>&>, void, true, void>, std::__call_is_nothrow<std::__invoke_result<B<args>::dispatch<double>::<lambda(auto:22& ...)>, A<int>&, A<float>&, A<double>&>, B<args>::dispatch<double>::<lambda(auto:22& ...)>, A<int>&, A<float>&, A<double>&> >' /home/jwakely/gcc/10/include/c++/10.2.1/type_traits:2979:12: [ skipping 7 instantiation contexts, use -ftemplate-backtrace-limit=0 to disable ] /home/jwakely/gcc/10/include/c++/10.2.1/type_traits:138:12: recursively required by substitution of 'template<class _Result, class _Ret> struct std::__is_invocable_impl<_Result, _Ret, true, std::__void_t<typename _CTp::type> > [with _Result = std::__invoke_result<C<bees>::fullDispatch<double>::<lambda(auto:23& ...)>, B<A<int>, A<float>, A<double> >&, B<A<double>, A<char>, A<bool> >&>; _Ret = void]' /home/jwakely/gcc/10/include/c++/10.2.1/type_traits:138:12: required from 'struct std::__and_<std::__is_invocable_impl<std::__invoke_result<C<bees>::fullDispatch<double>::<lambda(auto:23& ...)>, B<A<int>, A<float>, A<double> >&, B<A<double>, A<char>, A<bool> >&>, void, true, void>, std::__call_is_nothrow<std::__invoke_result<C<bees>::fullDispatch<double>::<lambda(auto:23& ...)>, B<A<int>, A<float>, A<double> >&, B<A<double>, A<char>, A<bool> >&>, C<bees>::fullDispatch<double>::<lambda(auto:23& ...)>, B<A<int>, A<float>, A<double> >&, B<A<double>, A<char>, A<bool> >&> >' /home/jwakely/gcc/10/include/c++/10.2.1/type_traits:2979:12: required from 'struct std::is_nothrow_invocable<C<bees>::fullDispatch<double>::<lambda(auto:23& ...)>, B<A<int>, A<float>, A<double> >&, B<A<double>, A<char>, A<bool> >&>' /home/jwakely/gcc/10/include/c++/10.2.1/tuple:1707:31: required from 'constexpr const bool std::__unpack_std_tuple<template<class _Fn, class ... _ArgTypes> struct std::is_nothrow_invocable, C<bees>::fullDispatch<double>::<lambda(auto:23& ...)>, std::tuple<B<A<int>, A<float>, A<double> >, B<A<double>, A<char>, A<bool> > >&>' /home/jwakely/gcc/10/include/c++/10.2.1/tuple:1730:14: required from 'constexpr decltype(auto) std::apply(_Fn&&, _Tuple&&) [with _Fn = C<bees>::fullDispatch<double>::<lambda(auto:23& ...)>; _Tuple = std::tuple<B<A<int>, A<float>, A<double> >, B<A<double>, A<char>, A<bool> > >&]' 96815.C:35:19: required from 'void C<bees>::fullDispatch(L) [with L = double; bees = {B<A<int>, A<float>, A<double> >, B<A<double>, A<char>, A<bool> >}]' 96815.C:48:24: required from here 96815.C:20:30: internal compiler error: in tsubst_pack_expansion, at cp/pt.c:12928 20 | std::apply([&](auto& ... a) { | ~~~~~~^~~~~ 0x5c4e33 tsubst_pack_expansion(tree_node*, tree_node*, int, tree_node*) /home/jwakely/src/gcc/gcc-10/gcc/cp/pt.c:12928 0x729a55 tsubst_decl /home/jwakely/src/gcc/gcc-10/gcc/cp/pt.c:14243 0x73162b tsubst_pack_expansion(tree_node*, tree_node*, int, tree_node*) /home/jwakely/src/gcc/gcc-10/gcc/cp/pt.c:12849 0x738f82 tsubst_fold_expr_pack /home/jwakely/src/gcc/gcc-10/gcc/cp/pt.c:12462 0x738f82 tsubst_unary_right_fold /home/jwakely/src/gcc/gcc-10/gcc/cp/pt.c:12578 0x738f82 tsubst_copy /home/jwakely/src/gcc/gcc-10/gcc/cp/pt.c:16983 0x72cd68 tsubst_copy_and_build(tree_node*, tree_node*, int, tree_node*, bool, bool) /home/jwakely/src/gcc/gcc-10/gcc/cp/pt.c:20567 0x724f84 tsubst_copy_and_build(tree_node*, tree_node*, int, tree_node*, bool, bool) /home/jwakely/src/gcc/gcc-10/gcc/cp/pt.c:19160 0x724f84 tsubst_expr(tree_node*, tree_node*, int, tree_node*, bool) /home/jwakely/src/gcc/gcc-10/gcc/cp/pt.c:18773 0x72613c tsubst_expr(tree_node*, tree_node*, int, tree_node*, bool) /home/jwakely/src/gcc/gcc-10/gcc/cp/pt.c:17840 0x72613c tsubst_expr(tree_node*, tree_node*, int, tree_node*, bool) /home/jwakely/src/gcc/gcc-10/gcc/cp/pt.c:17885 0x7267ae tsubst_expr(tree_node*, tree_node*, int, tree_node*, bool) /home/jwakely/src/gcc/gcc-10/gcc/cp/pt.c:17840 0x7267ae tsubst_expr(tree_node*, tree_node*, int, tree_node*, bool) /home/jwakely/src/gcc/gcc-10/gcc/cp/pt.c:17855 0x725b2b tsubst_expr(tree_node*, tree_node*, int, tree_node*, bool) /home/jwakely/src/gcc/gcc-10/gcc/cp/pt.c:17840 0x725b2b tsubst_expr(tree_node*, tree_node*, int, tree_node*, bool) /home/jwakely/src/gcc/gcc-10/gcc/cp/pt.c:18174 0x725b2b tsubst_expr(tree_node*, tree_node*, int, tree_node*, bool) /home/jwakely/src/gcc/gcc-10/gcc/cp/pt.c:17840 0x725b2b tsubst_expr(tree_node*, tree_node*, int, tree_node*, bool) /home/jwakely/src/gcc/gcc-10/gcc/cp/pt.c:18174 0x7267ae tsubst_expr(tree_node*, tree_node*, int, tree_node*, bool) /home/jwakely/src/gcc/gcc-10/gcc/cp/pt.c:17840 0x7267ae tsubst_expr(tree_node*, tree_node*, int, tree_node*, bool) /home/jwakely/src/gcc/gcc-10/gcc/cp/pt.c:17855 0x725b2b tsubst_expr(tree_node*, tree_node*, int, tree_node*, bool) /home/jwakely/src/gcc/gcc-10/gcc/cp/pt.c:17840 Please submit a full bug report, with preprocessed source if appropriate. Please include the complete backtrace with any bug report. See <https://gcc.gnu.org/bugs/> for instructions. Clang rejects it as invalid: <source>:21:55: error: type 'decltype(a)' (aka 'A<bool> &') cannot be used prior to '::' because it has no members ([&]{if constexpr(std::is_same_v<typename decltype(a)::type, K>) { a.doStuff(coolObject); }}(), ...); ^