【问题标题】:How to use a type with template as a template parameter in C++如何在 C++ 中使用带模板的类型作为模板参数
【发布时间】:2013-08-30 21:04:33
【问题描述】:

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

#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++ 中可行吗?

【问题讨论】:

  • 看起来你只是想要typename T
  • @chris 你是什么意思?我的应用程序中需要容器类型(例如vector)和底层类型(例如int)。
  • 您传入的是实例,而不是类模板本身(例如,func1&lt;vector&gt;()。该函数可能只是T t(1); 以产生相同的效果。请记住,并非所有容器都支持相同的操作。
  • @chris 你能写一个例子作为答案吗?我不确定我明白你的意思。

标签: c++ templates stl


【解决方案1】:

我认为最接近原始代码(假设您需要两个参数,CT 而不仅仅是一个 C&lt;T&gt;)如下:

#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&lt;T&gt;(其中T 是第一个参数)。你不能只用一个参数来定义模板;实例化时类型系统会报错。

  2. 1234563我冒昧地将容器修复为C&lt;T*&gt; 类型。

【讨论】:

    【解决方案2】:

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

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

    typename 需要一个类型 - 任何类型 - 这就是 vector&lt;int&gt;list&lt;float&gt; 等所得到的。另一方面,vector 本身只是一个模板,而不是一个单独的类型.这时候你就需要template&lt;template&lt;...&gt; class&gt; 语法了。

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

    【讨论】:

    • 我打算包装这些 STL 容器,以便它们具有相同的接口,这也意味着我需要在我的自定义类中使用一个名为 value_type 的字段,对吗?
    • @gokcehan,除其他外,您会(在标准中列为容器要求)。不过,在某种程度上,您必须区分不同类型的容器。
    【解决方案3】:

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

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

    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 了解更多信息。

    另一方面,正如 chris 在他的回答中注意到的那样,在您的情况下,传递类型参数并假设该类型具有成员类型 value_type 更容易,该成员类型用于获取容器元素的类型.

    【讨论】:

    • 我觉得这就是我正在寻找的东西,但它不能在我的机器上编译,error: use of undeclared identifier 'T' 说。我还需要ALLOCATOR 参数还是只是一个例子?
    【解决方案4】:

    首先new会返回一个指针,所以容器不会接受这个,改变那行,你也可以这样做:

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

    在主函数中:

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

    【讨论】:

    • 我喜欢这个解决方案。 func1&lt;vector&lt;int&gt;, int&gt; 中只有一点点冗余,但这并不令人烦恼。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-09
    • 1970-01-01
    相关资源
    最近更新 更多