如何在C ++中使用带有模板的类型作为模板参数

时间:2013-08-30 21:04:34

标签: c++ templates stl

我正在尝试使用具有相同功能的不同类型的不同类型的容器,但无法说服我的编译器。以下是我尝试过的一些事情:

#include <iostream>
#include <vector>
#include <list>
using namespace std;

// error: expected a qualified name after 'typename'
template<typename C<T>>
void func1() {
  C<T> c;
  c.push_back(new T);
}

// error: expected a qualified name after 'typename'
template<typename C<typename T>>
void func2() {
  C<T> c;
  c.push_back(new T);
}

// error: expected a qualified name after 'typename'
template<typename C<template <typename T>>>
void func3() {
  C<T> c;
  c.push_back(new T);
}

int main(int argc, char *argv[]) {
  func1<vector<int>>();
  func1<list<float>>();

  func2<vector<int>>();
  func2<list<float>>();

  func3<vector<int>>();
  func3<list<float>>();
  return 0;
}

这在C ++中是否可行?

4 个答案:

答案 0 :(得分:3)

我认为您最接近原始代码(假设您需要两个参数,CT而不只是一个C<T>),如下所示:

#include <iostream>
#include <vector>
#include <list>
using namespace std;

template<template< class T, class A = allocator<T> > class C, typename T>
void func() {
  C<T*> c;
  c.push_back(new T);
}

int main(int argc, char *argv[]) {
  func<vector, int>();
  func<list, float>();
  return 0;
}

注意两件事:

  1. vectorlist模板有两个参数,第二个参数默认为allocator<T>(其中T是第一个参数)。您不能只使用一个参数定义模板;类型系统在实例化时会抱怨。

  2. 如果您的容器类型为C<T>push_back方法需要T(例如vectorlist),则不能传递它new T作为参数。我冒昧地将容器固定为C<T*>类型。

答案 1 :(得分:2)

我认为您在谈论 “模板模板参数”

模板模板参数是一种类型模板参数,仅允许模板类。该类模板可以具有任何类型的模板参数。例如:

template<template<typename T , typename ALLOCATOR> class CONTAINER>
void func2()
{
    CONTAINER<T,ALLOCATOR> container;

    container.push_back( T() );
} 

int main()
{
    func2<std::vector<bool>>();
}

当您需要提取已作为模板参数传递的类模板的模板参数时,这非常有用 结帐this question了解详情。

另一方面,正如克里斯在他的回答中所注意到的,在你的情况下,它更容易传递一个类型参数,并假设该类型有一个成员类型value_type,用于获取元素的类型容器。

答案 2 :(得分:2)

从你的电话中,我怀疑你只是想要这样的东西(我会让代码尽可能接近你所拥有的并保持C ++ 03):

template<typename T>
void func1() {
    T t;
    t.push_back(typename T::value_type());
}

typename需要一种类型 - 任何类型 - 这就是vector<int>list<float>等所带来的类型。另一方面,vector本身只是一个模板,而不是自己的类型。那时你需要template<template<...> class>语法。

但请注意,尝试对此类容器进行分组通常不起作用,因为并非每个容器都支持与其他容器相同的操作。如果你需要这样的接口,你必须区分序列容器,关联容器等。

答案 3 :(得分:1)

首先new将返回一个指针,因此容器不接受这个,更改该行,你也可以执行以下操作:

template<typename Container, typename T >
void func1() {
  Container c;
  c.push_back(T());
}

并在主要功能中:

func1<std::vector<int>, int >();