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.