I am trying to explicitly instantiate a class with multiple different parameters.
// This is the class I want to explicitly instantiate
template <typename arg1, typename arg2>
class Foo{};
// This a helper meta-function to compute the template parameters for the above class
template <typename helper1, typename helper2>
class instantiation_helper{
using arg1 = helper1; // actually some_constexpr_function(helper1, helper2)
using arg2 = helper2; // actually some_constexpr_function(helper1 , helper2)
};
One trivial solution is verbose:
using helper0 = instantiation_helper<int, int>;
template class Foo<helper0::arg1, helper0::arg2>;
using helper1 = instantiation_helper<float, int>;
template class Foo<helper1::arg1, helper1::arg2>;
using helper2 = instantiation_helper<int, float>;
template class Foo<helper2::arg1, helper2::arg2>;
using helper3 = instantiation_helper<float, float>;
template class Foo<helper3::arg1, helper3::arg2>;
So I am storing the type of the Foo class in the helper meta-function itself and then instantiating using that:
template <typename helper1, typename helper2>
class instantiation_helper{
using arg1 = helper1; // actually some_constexpr_function(helper1, helper2)
using arg2 = helper2; // actually some_constexpr_function(helper1, helper2)
using Foo_type = Foo<arg1, arg2>;
};
template instantiation_helper<int, int>::Foo_type;
template instantiation_helper<int, float>::Foo_type;
template instantiation_helper<float, int>::Foo_type;
template instantiation_helper<float, float>::Foo_type;
But this errors out with:
prog.cpp:13:50: error: expected unqualified-id before ‘;’ token
template instantiation_helper<int, int>::Foo_type;
I guess this is because Foo_type does not qualify as simple-template-id (using typedef in template instantiation and extern template declaration).
So I am trying to instead store the template arguments as a tuple and then expand them later when explicitly instantiating:
template <typename helper1, typename helper2>
class instantiation_helper{
using arg1 = helper1; // actually some_constexpr_function(helper1, helper2)
using arg2 = helper2; // actually some_constexpr_function(helper1, helper2)
using Foo_template_params = std::tuple<arg1, arg2>;
};
using arg_list1 = instantiation_helper<int, int>::Foo_template_params;
template class Foo<std::tuple_element<0, arg_list1>::type, std::tuple_element<1, arg_list1>::type>;
using arg_list2 = instantiation_helper<float, int>::Foo_template_params;
template class Foo<std::tuple_element<0, arg_list2>::type, std::tuple_element<1, arg_list2>::type>;
using arg_list3 = instantiation_helper<int, float>::Foo_template_params;
template class Foo<std::tuple_element<0, arg_list3>::type, std::tuple_element<1, arg_list3>::type>;
using arg_list4 = instantiation_helper<float, float>::Foo_template_params;
template class Foo<std::tuple_element<0, arg_list4>::type, std::tuple_element<1, arg_list4>::type>;
This obviously again is verbose and I am not even sure if tuple is the right way of doing this.
So my question is:
- How would one go about achieving this?
- What if Foo had a third variadic template parameter like
template <typename arg1, typename arg2, typename ...arg3>
class Foo{};