使用typename作为模板参数

时间:2013-11-02 22:05:49

标签: c++

我正在尝试编写一个函数来在C ++中打印std列表。对模板函数来说,T不能用作模板参数吗?

template <typename T>
void printlist(list<T> a)
{
    list<T>::iterator i;
    for (i=a.begin(); i!=a.end(); ++i)
        cout<<*i<<" ";
}

3 个答案:

答案 0 :(得分:4)

好像你正在使用C ++ 03标准,为了解析C ++程序,编译器需要知道某些名称它们的名称是 types 还是< EM>非类型

要解决您的问题,您需要在typename之前添加list<T>::iterator才能使其正常工作

template <typename T>
void printlist(list<T> a)
{
    typename list<T>::iterator i;
    for (i=a.begin(); i!=a.end(); ++i)
        cout << *i << " ";
}

答案 1 :(得分:4)

代码大多是合法的。有些编译器可能会接受它......但是,按照以下方式编写它肯定会起作用(假设你已定义using namespace std):

template <typename T>
void printlist(list<T> a)
{
    typename list<T>::iterator i;
    for (i=a.begin(); i!=a.end(); ++i)
        cout<<*i<<" ";
}

为了提高效率,您应该将列表作为const引用传递:

template <typename T>
void printlist(const list<T>& a)
{
    typename list<T>::const_iterator i;
    for (i=a.begin(); i!=a.end(); ++i)
        cout<<*i<<" ";
}

但是,有一种STL算法已经为您完成此操作。假设您要打印出整数列表,请写下:

copy( a.begin(), a.end(), ostream_iterator<int>( cout, " " ) );

只需用适当的元素类型替换int即可。注意:此算法适用于任何序列。

答案 2 :(得分:-2)

您确定模板名称list正在解析为std::list吗?

编辑:您忘记了typename关键字。编译器错误消息几乎总是说“依赖类型所需的类型名称”。这强调了在发布问题时需要包含错误消息。

其他反馈:

  • 构造像i这样的迭代器然后稍后进行初始化是不好的做法。 最好写list<T>::iterator i = a.begin();这可能是for循环的一部分。
  • 您可以使用const_iterator
  • 您按值传递列表,而不是通过const引用传递。换句话说,这个声明会更好:void printlist(const std::list<T>& a)