模板方法中的std容器

时间:2011-02-27 19:03:51

标签: c++ templates containers std

问候。

我不太清楚如何解释自己,但我相信一段代码会让你理解我想要做的事情:

template<class A, class B>
void myFunction(A<B>& list)
{
  typename A<B>::iterator current = list.begin();
  typename A<B>::iterator end = list.end();

  while (current != end)
  {
    current++;
  }
}

其中A是STL容器(vector,list ...)。它就像开始一样,但有模板:模板,模板内等......

问题是:当你的模板的一个参数本身就是一个模板时,你会怎么做......并且仍然希望支持这个模板支持的每种类型。

这当然不能编译(它说“A不是模板”)。

有人知道如何创建这样的模板吗?

3 个答案:

答案 0 :(得分:7)

您正在寻找模板模板参数

template<template<class T, class All = std::allocator<T> > class A, class B>
void myFunction(A<B>& list)
{
  typename A<B>::iterator current = list.begin();
  typename A<B>::iterator end = list.end();

  while (current != end)
  {
    current++;
  }
}

但是,在您的特定情况下,我认为通过传递实例化的容器会更好,也就是说,

template<class C>
void myFunction(C& list)
{
   ...
}

像这样使用

vector<char> v;
myFunction(v);

您的原始代码必须像这样调用:

myFunction<std::vector, char> (v)

更冗长,没有特别的好处

答案 1 :(得分:2)

AB将是具体类型(而不是模板),因此A<B>毫无意义。

您可以这样编写代码:

template<class List>
void myFunction(List &list)
{
  typename List::iterator current = list.begin();
  typename List::iterator end = list.end();

  while (current != end)
  {
    current++;
  }
}

如果您需要知道该列表中元素的类型,列表中有一个typedef:

typename List::value_type

答案 2 :(得分:-1)

嗯,要解决这个小例子问题。这很简单。 vector<int>是一个类,因此,您不需要在原型中声明A<B>。你可以这样做:

template<class A>
void myFunction(A& list)
{
  typedef typename A::value_type B; //do this if you need to know the type of the elements.
  typename A::iterator current = list.begin();
  typename A::iterator end = list.end();

  while (current != end)
  {
    current++;
  }
}

但是如果你真的需要,你也可以将模板参数声明为模板:

template< template<class> class A, class B >
void myFunction(A<B>& list)
{
  typename A<B>::iterator current = list.begin();
  typename A<B>::iterator end = list.end();

  while (current != end)
  {
    current++;
  }
}

但上面并不是真的推荐,大多数类模板都有一组嵌套的typedef(比如STL容器中的iterator和value_type),这样你就可以访问了你需要的关于类型的所有信息,而不必使用这些模板模板参数。因此,第一种方法通常是首选和更常规的方法(使它工作通常也不那么麻烦,即编译器倾向于“不喜欢”模板​​模板参数)。

此外,您无法使用模板模板参数非常轻松地使用STL容器,因为STL容器都具有这些“隐藏”模板参数(例如“allocator”和“compare”用于已排序的容器)。所以,你必须列出所有这些,否则编译器将无法进行匹配。然后,你将没有一个非常“通用”的功能,因为你将不得不假设过去的STL容器,它只会提供一种或两种类型的容器。使用第一种方式真的更好。