首页 > 解决方案 > 使用 typedef 显式模板实例化

问题描述

我正在尝试用多个不同的参数显式实例化一个类。

// 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)
};

一个简单的解决方案是冗长的:

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>;

所以我将 Foo 类的类型存储在辅助元函数本身中,然后使用它进行实例化:

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;

但这会出错:

prog.cpp:13:50: error: expected unqualified-id before ‘;’ token
 template instantiation_helper<int, int>::Foo_type;

我猜这是因为 Foo_type 不符合simple-template-id在模板实例化和 extern 模板声明中使用 typedef)。

所以我试图将模板参数存储为一个元组,然后在显式实例化时扩展它们:

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>;

这显然又是冗长的,我什至不确定 tuple 是否是这样做的正确方法。

所以我的问题是:

  1. 如何实现这一目标?
  2. 如果 Foo 有第三个可变参数模板参数,例如
template <typename arg1, typename arg2, typename ...arg3>
class Foo{};

标签: c++templatesc++17metaprogrammingtemplate-meta-programming

解决方案


推荐阅读