首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >将迭代器作为函数参数传递

将迭代器作为函数参数传递
EN

Stack Overflow用户
提问于 2013-11-27 14:12:36
回答 2查看 44.2K关注 0票数 17

我试图编写一个函数,它将对容器的元素进行求和。这个容器可以是向量、列表、队列等.这就是我尝试模板的原因。

不幸的是,我得到了这个错误:

“c”不是模板

来源:

代码语言:javascript
运行
复制
#include <iostream>
#include <vector>

using namespace std;

template<class C, typename T>
T sum( C<T>::iterator begin, C<T>::iterator end ) {
    T s = null;

    for (C<T>::iterator it = begin; it != end; it++) {
        s += *it;
    }

    return s;
}

int main()
{
    vector<int> v = {5, 9, 0, 11};

    cout << sum(v.begin(), v.end()) << endl;

    return 0;
}

我做错什么了?我该怎么修呢?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-11-27 14:20:24

您得到的特别错误是因为您需要一个模板参数:

代码语言:javascript
运行
复制
template<template <typename> class C, typename T>
//       ^^^^^^^^^^^^^^^^^^^^^^^^^^^
T sum( C<T>::iterator begin, C<T>::iterator end )

但是,标准容器通常不只是一个模板参数:

代码语言:javascript
运行
复制
template < class T, class Alloc = allocator<T> > class vector

正确地编写这样的函数是有点不平凡的。您可以使用各种模板参数,也可以像标准库那样使用这些参数,并且只专门处理您真正需要的内容:

代码语言:javascript
运行
复制
// <algorithm>
namespace std {
    template <class RandomAccessIterator>
    void sort (RandomAccessIterator first, RandomAccessIterator last);
}

在您的情况下(假装标准算法库已经没有满足您的需要):

代码语言:javascript
运行
复制
template <typename Iterator>
auto sum(Iterator begin, Iterator end) 
-> decltype(*begin+*begin) // the type of summing two of them
{
    if (begin == end) throw std::logic_error("....");
    auto s = *begin;
    ++begin;
    for (; begin != end; ++begin) {
        s += *begin;
    }
    return s;
}

与原始代码相比,还有一些不同之处:

  • 新代码不假定为null或默认构造函数(T s = null;)。
  • 不引入附加迭代器(it)
  • 使用预增量
  • 当begin==end引发异常时

如果添加init参数,则几乎可以使其成为noexcept

代码语言:javascript
运行
复制
template <typename Iterator, typename T>
T sum(Iterator begin, Iterator end, T init)
{
    for (; begin!=end; ++begin)
        init += *begin;
    return init;
}

但只有几乎,因为init += *begin仍然可以扔。

如果您有这样的签名,顺便说一句,您已经复制了std::accumulate的签名。

票数 11
EN

Stack Overflow用户

发布于 2013-11-27 14:14:56

您可以用迭代器类型来表示整个过程,并使用iterator_traits获取value_type:

代码语言:javascript
运行
复制
#include <iterator>

template<typename Iterator>
typename std::iterator_traits<Iterator>::value_type 
sum(Iterator begin, Iterator end)
{
  using value_type = typename std::iterator_traits<Iterator>::value_type;
  value_type s = value_type();
  for (Iterator it = begin; it != end; it++) {
    s += *it;
  }
  return s;
}

在现实生活中,使用std::累积

代码语言:javascript
运行
复制
int sum = std::accumulate(v.begin(), v.end(), 0);
票数 23
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20244743

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档