https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93992
Bug ID: 93992 Summary: faile to compile specialization of inner class with template template parameter pack Product: gcc Version: 10.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: yawaraka.7-11.hemogurobin at ezweb dot ne.jp Target Milestone: --- // Source #include <iostream> #include <type_traits> #include <typeinfo> #include <array> template<typename T, T... Value> class A { }; template<typename T, template<T...> class, T...> struct args_union; template<typename T, template<T...> class TemplateType, T Head, T... Tail> struct args_union<T, TemplateType, Head, Tail...> { template<T...> struct args_union_sub; template<T Head2, T... Tail2> struct args_union_sub<Head2, Tail2...> { template<T... Args> using template_type = std::conditional_t<(Head2 < Head), TemplateType<Head2, Args...>, // if (Head2 < Head) TemplateType<Head2, Args...>; TemplateType<Head, Args...>>; // else TemplateType<Head, Args...>; using type = std::conditional_t<Head == Head2, // if (Head == Head2) typename args_union<T, template_type, Tail...>::template args_union_sub<Tail2...>::type, // args_union、args_union_sub std::conditional_t<(Head < Head2), // else if (Head < Head2) typename args_union<T, template_type, Tail...>::template args_union_sub<Head2, Tail2...>::type, // args_union // else typename args_union<T, template_type, Head, Tail...>::template args_union_sub<Tail2...>::type>>;// args_union_sub }; template<> struct args_union_sub<> { template<T... Args> using template_type = TemplateType<>; using type = TemplateType<Head, Tail...>; }; }; template<typename T, template<T...> class TemplateType> struct args_union<T, TemplateType> { template<T...> struct args_union_sub; template<T Head2, T... Tail2> struct args_union_sub<Head2, Tail2...> { template<T... Args> using template_type = TemplateType<Head2, Tail2..., Args...>; using type = TemplateType<Head2, Tail2...>; }; template<> struct args_union_sub<> { template<T... Args> using template_type = TemplateType<>; using type = TemplateType<>; }; }; template<typename T> struct Asub { template<T... Value> using type = A<T, Value...>; }; template<typename T, T... Value1, T... Value2> constexpr auto tmp_union(const A<T, Value1...>&, const A<T, Value2...>&) { return typename args_union<T, Asub<T>::template type, Value1...>::template args_union_sub<Value2...>::type(); } int main() { A<int, 0, 1, 4, 6> a; A<int, 1, 2, 4, 5> b; std::cout << std::boolalpha << std::is_same_v<decltype(tmp_union(a, b)), A<int, 0, 1, 2, 4, 5, 6>> << std::endl; std::cout << typeid(tmp_union(a, b)).name() << std::endl; } // error message Using built-in specs. COLLECT_GCC=/opt/wandbox/gcc-head/bin/g++ COLLECT_LTO_WRAPPER=/opt/wandbox/gcc-head/libexec/gcc/x86_64-pc-linux-gnu/10.0.1/lto-wrapper Target: x86_64-pc-linux-gnu Configured with: ../source/configure --prefix=/opt/wandbox/gcc-head --enable-languages=c,c++ --disable-multilib --without-ppl --without-cloog-ppl --enable-checking=release --disable-nls --enable-lto LDFLAGS=-Wl,-rpath,/opt/wandbox/gcc-head/lib,-rpath,/opt/wandbox/gcc-head/lib64,-rpath,/opt/wandbox/gcc-head/lib32 Thread model: posix Supported LTO compression algorithms: zlib gcc version 10.0.1 20200229 (experimental) (GCC) COLLECT_GCC_OPTIONS='-o' 'prog.exe' '-I' '/opt/wandbox/boost-sml/include' '-I' '/opt/wandbox/boost-di/include' '-I' '/opt/wandbox/range-v3/include' '-I' '/opt/wandbox/nlohmann-json/include' '-I' '/opt/wandbox/cmcstl2/include' '-I' '/opt/wandbox/te/include' '-Wall' '-Wextra' '-O2' '-march=native' '-v' '-std=gnu++2a' '-I' '/opt/wandbox/boost-1.72.0/gcc-head/include' '-L/opt/wandbox/boost-1.72.0/gcc-head/lib' '-shared-libgcc' /opt/wandbox/gcc-head/libexec/gcc/x86_64-pc-linux-gnu/10.0.1/cc1plus -quiet -v -I /opt/wandbox/boost-sml/include -I /opt/wandbox/boost-di/include -I /opt/wandbox/range-v3/include -I /opt/wandbox/nlohmann-json/include -I /opt/wandbox/cmcstl2/include -I /opt/wandbox/te/include -I /opt/wandbox/boost-1.72.0/gcc-head/include -imultiarch x86_64-linux-gnu -D_GNU_SOURCE prog.cc -march=sandybridge -mmmx -mno-3dnow -msse -msse2 -msse3 -mssse3 -mno-sse4a -mcx16 -msahf -mno-movbe -maes -mno-sha -mpclmul -mpopcnt -mno-abm -mno-lwp -mno-fma -mno-fma4 -mno-xop -mno-bmi -mno-sgx -mno-bmi2 -mno-pconfig -mno-wbnoinvd -mno-tbm -mavx -mno-avx2 -msse4.2 -msse4.1 -mno-lzcnt -mno-rtm -mno-hle -mno-rdrnd -mno-f16c -mno-fsgsbase -mno-rdseed -mno-prfchw -mno-adx -mfxsr -mxsave -mxsaveopt -mno-avx512f -mno-avx512er -mno-avx512cd -mno-avx512pf -mno-prefetchwt1 -mno-clflushopt -mno-xsavec -mno-xsaves -mno-avx512dq -mno-avx512bw -mno-avx512vl -mno-avx512ifma -mno-avx512vbmi -mno-avx5124fmaps -mno-avx5124vnniw -mno-clwb -mno-mwaitx -mno-clzero -mno-pku -mno-rdpid -mno-gfni -mno-shstk -mno-avx512vbmi2 -mno-avx512vnni -mno-vaes -mno-vpclmulqdq -mno-avx512bitalg -mno-movdiri -mno-movdir64b -mno-waitpkg -mno-cldemote -mno-ptwrite -mno-avx512bf16 -mno-enqcmd -mno-avx512vp2intersect --param l1-cache-size=32 --param l1-cache-line-size=64 --param l2-cache-size=4096 -mtune=sandybridge -quiet -dumpbase prog.cc -auxbase prog -O2 -Wall -Wextra -std=gnu++2a -version -o /tmp/cczxYwwS.s GNU C++17 (GCC) version 10.0.1 20200229 (experimental) (x86_64-pc-linux-gnu) compiled by GNU C version 10.0.1 20200229 (experimental), GMP version 6.1.0, MPFR version 3.1.4, MPC version 1.0.3, isl version none GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu" ignoring nonexistent directory "/usr/local/include" ignoring nonexistent directory "/opt/wandbox/gcc-head/lib/gcc/x86_64-pc-linux-gnu/10.0.1/../../../../x86_64-pc-linux-gnu/include" #include "..." search starts here: #include <...> search starts here: /opt/wandbox/boost-sml/include /opt/wandbox/boost-di/include /opt/wandbox/range-v3/include /opt/wandbox/nlohmann-json/include /opt/wandbox/cmcstl2/include /opt/wandbox/te/include /opt/wandbox/boost-1.72.0/gcc-head/include /opt/wandbox/gcc-head/lib/gcc/x86_64-pc-linux-gnu/10.0.1/../../../../include/c++/10.0.1 /opt/wandbox/gcc-head/lib/gcc/x86_64-pc-linux-gnu/10.0.1/../../../../include/c++/10.0.1/x86_64-pc-linux-gnu /opt/wandbox/gcc-head/lib/gcc/x86_64-pc-linux-gnu/10.0.1/../../../../include/c++/10.0.1/backward /opt/wandbox/gcc-head/lib/gcc/x86_64-pc-linux-gnu/10.0.1/include /opt/wandbox/gcc-head/include /opt/wandbox/gcc-head/lib/gcc/x86_64-pc-linux-gnu/10.0.1/include-fixed /usr/include/x86_64-linux-gnu /usr/include End of search list. GNU C++17 (GCC) version 10.0.1 20200229 (experimental) (x86_64-pc-linux-gnu) compiled by GNU C version 10.0.1 20200229 (experimental), GMP version 6.1.0, MPFR version 3.1.4, MPC version 1.0.3, isl version none GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 Compiler executable checksum: 1af50902123577608ff32d1ca7d8f798 prog.cc:24:11: error: explicit specialization in non-namespace scope 'struct args_union<T, TemplateType, Head, Tail ...>' 24 | template<> struct args_union_sub<> { | ^ prog.cc:24:20: error: template parameters not deducible in partial specialization: 24 | template<> struct args_union_sub<> { | ^~~~~~~~~~~~~~~~ prog.cc:24:20: note: 'T' prog.cc:24:20: note: 'template<T ...<anonymous> > class TemplateType' prog.cc:24:20: note: 'Head' prog.cc:24:20: note: 'Tail' prog.cc:36:11: error: explicit specialization in non-namespace scope 'struct args_union<T, TemplateType>' 36 | template<> struct args_union_sub<> { | ^ prog.cc:36:20: error: template parameters not deducible in partial specialization: 36 | template<> struct args_union_sub<> { | ^~~~~~~~~~~~~~~~ prog.cc:36:20: note: 'T' prog.cc:36:20: note: 'template<T ...<anonymous> > class TemplateType' prog.cc: In instantiation of 'struct args_union<int, args_union<int, args_union<int, args_union<int, Asub<int>::type, 0, 1, 4, 6>::args_union_sub<1, 2, 4, 5>::template_type, 1, 4, 6>::args_union_sub<2, 4, 5>::template_type, 4, 6>::args_union_sub<4, 5>::template_type, 6>::args_union_sub<5>': prog.cc:17:9: recursively required from 'struct args_union<int, args_union<int, Asub<int>::type, 0, 1, 4, 6>::args_union_sub<1, 2, 4, 5>::template_type, 1, 4, 6>::args_union_sub<2, 4, 5>' prog.cc:17:9: required from 'struct args_union<int, Asub<int>::type, 0, 1, 4, 6>::args_union_sub<1, 2, 4, 5>' prog.cc:47:104: required from 'constexpr auto tmp_union(const A<T, Value1 ...>&, const A<T, Value2 ...>&) [with T = int; T ...Value1 = {0, 1, 4, 6}; T ...Value2 = {1, 2, 4, 5}]' prog.cc:53:74: required from here prog.cc:17:9: error: invalid use of incomplete type 'struct args_union<int, args_union<int, args_union<int, args_union<int, args_union<int, Asub<int>::type, 0, 1, 4, 6>::args_union_sub<1, 2, 4, 5>::template_type, 1, 4, 6>::args_union_sub<2, 4, 5>::template_type, 4, 6>::args_union_sub<4, 5>::template_type, 6>::args_union_sub<5>::template_type>::args_union_sub<>' 17 | using type = std::conditional_t<Head == Head2, // if (Head == Head2) | ^~~~ prog.cc:31:24: note: declaration of 'struct args_union<int, args_union<int, args_union<int, args_union<int, args_union<int, Asub<int>::type, 0, 1, 4, 6>::args_union_sub<1, 2, 4, 5>::template_type, 1, 4, 6>::args_union_sub<2, 4, 5>::template_type, 4, 6>::args_union_sub<4, 5>::template_type, 6>::args_union_sub<5>::template_type>::args_union_sub<>' 31 | template<T...> struct args_union_sub; | ^~~~~~~~~~~~~~ prog.cc: In function 'int main()': prog.cc:53:41: error: template argument 1 is invalid 53 | std::cout << std::boolalpha << std::is_same_v<decltype(tmp_union(a, b)), A<int, 0, 1, 2, 4, 5, 6>> << std::endl; | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // command line $ g++ prog.cc -Wall -Wextra -O2 -march=native -v -I/opt/wandbox/boost-1.72.0/gcc-head/include -std=gnu++2a // comment compiled on Wandbox. URL: https://wandbox.org/permlink/7hblGLSOhTyVBK4V Clang 11.0.0 and MSVC 16.4.5 compile this code successfully.