为什么我不能创建这样的模板函数?

时间:2013-10-18 07:49:39

标签: c++ templates vector helper-functions

我试图使用帮助函数打印vector<int>,如下所示:

这不起作用 -

template<class T>
void print(const std::vector<T>& v)
{
    std::vector<T>::const_iterator i;
    for (i = v.begin(); i != v.end(); i++)
        std::cout << *i << "  ";
    std::cout << std::endl;
}

编辑:我明白了。

Error

但这有效 -

template<class T>
void print(const std::vector<T>& v)
{
    // changed std::vector<T> to std::vector<int>
    std::vector<int>::const_iterator i;
    for (i = v.begin(); i != v.end(); i++)
        std::cout << *i << "  ";
    std::cout << std::endl;
}

我想问下列事项:

  • 为什么第一个不起作用,第二个不起作用?
  • 为同一功能编写函数的其他方法有哪些? 附:我不希望在函数内部更改任何元素。我想可以使用for_each()算法来完成。但我不确定如何为它编写谓词。

3 个答案:

答案 0 :(得分:4)

你应该使用

typename std::vector<T>::const_iterator i;

使它工作(正如编译器在错误消息中告诉你的那样)。

const_iterator在第一种情况下是依赖于模板的名称,因此您必须使用该关键字来消除歧义。

请按照Joachim Pileborg的评论中的链接获得一个很好的解释。

答案 1 :(得分:4)

std::vector<T>::const_iterator是一个从属名称,您需要在前面添加typename

typename std::vector<T>::const_iterator i;

或者只是这样写:

for (auto it  = v.begin(); it != v.end(); ++it) {
    std::cout << *it << "  ";
}

或者

for (auto const& e : v) 
{
   cout << e << "\n";
}
std::cout << std::endl;

什么是依赖名称

  

以某种方式依赖于模板参数的名称。当然,任何明确包含模板参数的限定或非限定名称都是相关的。此外,如果访问运算符左侧的表达式类型取决于模板参数,则由成员访问运算符(。或 - &gt;)限定的限定名称是相关的。特别地,这个 - > b中的b是它出现在模板中时的从属名称。最后,当且仅当任何参数表达式具有依赖于模板参数的类型时,形式为ident(x,y,z)的调用中的标识符ident是从属名称。

答案 2 :(得分:2)

  
      
  • 为什么第一个不起作用,第二个不起作用?
  •   

因为你忽略了错误

typename std::vector<T>::const_iterator i;
^^^Use typename
  
      
  • 为同一功能编写函数的其他方法有哪些?附:我不希望在函数内部更改任何元素。我想可以使用for_each()算法来完成。但我不确定如何为它编写谓词。
  •   
struct foo{
    void operator()(const int &i) const{
        std::cout<<i<<"  ";
    }
}
for_each(v.begin(), v.end(),foo());
相关问题