While trying to use a compile time std::array in a variadic template, I wrote this partial template specialization:
template <typename array_wrapper> struct Test1;
template <std::size_t... A> struct Test1<any_type<std::array<std::size_t, sizeof...(A)>{A...}>> {}; //(2)
which leads to a compilation error <Expression> has incomplete type and cannot be defined
for my attempts to partial template specialization for Test1
and Test2
when I am trying to use it; hence -- as I understand it -- the usage (3) does not match the definition (2):
int main() {
Test1<any_type<std::array<std::size_t, 2>{1, 2}>> a; // (3)
}
I don't understand why this is the case though. When experimenting with the example, I realize that this happens when I am 'hiding' the content of the parameter pack in my any_type
struct:
#include <array>
template <auto f> struct any_type;
template <typename array_wrapper> struct Test1;
template <std::size_t... A> struct Test1<any_type<std::array<std::size_t, sizeof...(A)>{A...}>> {};
template <typename array_wrapper> struct Test2;
template <int... A> struct Test2<any_type<std::get<0>(A...)>> {};
template <typename array_wrapper> struct Test3;
template <int A> struct Test3<any_type<A>> {};
int main() {
//Test1<any_type<std::array<std::size_t, 2>{1, 2}>> a;
//Test2<any_type<1>> b;
Test3<any_type<1>> ok;
}
Test1 and Test2 fail with the same error, and Test3 works fine. Why does the partial template specialization 'fail' in the frist two cases? As I understand it, the declaration provides the 'interface' in order to use the struct, and the arguments in the specialization are matched to teh arguments which are actually provided.
Code The code can be found here.
Compile options:
I useg++-10.0 (GCC) 10.0.1 20200124 (experimental)
and compile via g++ -std=c++2a file.cc
, c++2a is required because I use non-type template parameters.