I tried to specialize Expr:
#include <tuple>
#include <type_traits>
#include <iostream>
template<class Tp, class List>
struct Expr {
Expr(){std::cout << "0"<< std::endl;};
};
template<class Tp, int...i>
struct Expr<Tp,std::tuple<std::integral_constant<int,i>...>> {
Expr(){std::cout << "1"<< std::endl;};
};
template<int...i>
struct Expr<double,std::tuple<std::integral_constant<int,i>...>> {
Expr(){std::cout << "2"<< std::endl;};
};
int main() {
typedef std::tuple<std::integral_constant<int,1>> mylist;
Expr<double,mylist> test{};
return 0;
}
However, I received the following compiler errors:
[x86-64 gcc 6.3] error: ambiguous template instantiation for 'struct Expr<double, std::tuple<std::integral_constant<int, 1> > >'
[x86-64 gcc 6.3] error: variable 'Expr<double, std::tuple<std::integral_constant<int, 1> > > test' has initializer but incomplete type
Here, especially the first mistake bothers me. I tried to understand why this is an ambiguous creation.
Shouldn't I choose a specialization #2compiler?
If I manage without a package of packages int...iin std::integral_constantthat does not execute, it compiles without any problems and the second specialization is selected. The following example works:
#include <tuple>
#include <type_traits>
#include <iostream>
template<class Tp, class List>
struct Expr {
Expr(){std::cout << "0"<< std::endl;};
};
template<class Tp, class...args>
struct Expr<Tp,std::tuple<args...>> {
Expr(){std::cout << "1"<< std::endl;};
};
template<class...args>
struct Expr<double,std::tuple<args...>> {
Expr(){std::cout << "2"<< std::endl;};
};
int main() {
typedef std::tuple<std::integral_constant<int,1>> mylist;
Expr<double,mylist> test{};
return 0;
}