是否可以在C++中"bundle"模板参数?

Is it possible to "bundle" template parameters in C++?

本文关键字:bundle 参数 C++ 是否      更新时间:2023-10-16

有没有办法将模板参数"捆绑"在一起以避免重复?

我有几个类和函数都使用相同的三个模板参数。 拥有一个使用每个类/函数一次的函数并不罕见。 生成的代码很快就会变得非常混乱。有没有更简洁的方法来编写此代码?

// ContextFactory is a pointer to functions that instantiate objects that are subtypes of MetricContext
template<typename VertexID, typename EdgeMembershipType, typename SetBitmap>
using ContextFactory = MetricContext <VertexID, EdgeMembershipType, SetBitmap> *(*)(const char *);
template<typename VertexID, typename EdgeMembershipType, typename SetBitmap>
    static vector<ContextFactory<VertexID, EdgeMembershipType, SetBitmap>> buildCFList() {
      vector<ContextFactory<VertexID, EdgeMembershipType, SetBitmap>> answer;
      answer.push_back(MetricContext<VertexID, EdgeMembershipType, SetBitmap>::template make<NeoContext<VertexID, EdgeMembershipType, SetBitmap >>);
      return answer;
    };

请注意,这个函数几乎有一半是字符串<VertexID, EdgeMembershipType, SetBitmap>>的重复,但是这个字符串的每次使用都适用于不同的类或函数,所以我认为别名不起作用。

(如果有帮助,此函数的目的是创建一个指向函数的指针数组,这些函数将创建作为MetricContext<VertexID, EdgeMembershipType, SetBitmap>>子类型的对象

比@Quentin更具体的方法是让你的模板依赖于单个参数 - 该参数应该具有VertexIDEdgeMembershipTypeSetBitmap的 typedefs。

// ContextFactory is a pointer to functions that instantiate objects that are 
// subtypes of MetricContext
template<typename Types>
using ContextFactory = MetricContext <Types> *(*)(const char *);
template<typename Types>
    static vector<ContextFactory<Types>> buildCFList() {
      vector<ContextFactory<Types>> answer;
      answer.push_back(MetricContext<Types>::template make<NeoContext<Types>>);
      return answer;
    };

请注意,当您想实际使用其中一个 typedefs 时,您需要使用例如:typename Types::VertexID .

(理想情况下,你会为模板参数想出一个比Types更好的名称。

是的,这是可能的。让我们定义一个小的帮助程序类来保存类型列表:

template <class... > struct pack { };

还有一个元函数,它用pack里面的内容实例化模板:

template <template <class... > class T, class P>
struct unpack_;
template <template <class... > class T, class... P>
struct unpack_<T, pack<P...>> {
    using type = T<P...>;
};
template <template <class... > class T, class P>
using unpack = typename unpack_<T, P>::type;

现在我们可以存储和使用我们的参数包:

template <class A, class B, class C>
struct Foo { };
using Params = pack<int, float, double>;
unpack<Foo, Params> f; // f is a Foo<int, float, double>

在科里鲁现场观看

如果你使用的是C++11,你可以使用std::tuple将变量组合成一个。

一个更简单的例子来理解相同可能是

template <typename A, typename B, typename C>
void fn() {
 typedef std::tuple<A,B,C> myTuple;
  myTuple tpl;
  cout<<sizeof(std::get<0>(tpl))<<endl;;
  cout<<sizeof(std::get<1>(tpl))<<endl;
  cout<<sizeof(std::get<2>(tpl))<<endl;
}
int main() {
 fn<int,char,long>();
 return 0;
}

对于特定于您的问题的问题,您可以将元组的向量创建

template <typename A, typename B, typename C>
void fn() {
    using mycomb = std::tuple<A,B,C>;
    vector<mycomb> v1;
    v1.push_back(make_tuple(10,'c',20.0));
}

这样,您无需重复相同的操作。元组 getter 函数一开始有点尴尬。上面的cout示例演示了如何访问元组参数

希望这有帮助