使用迭代器将"哑"函数重构为通用STL样式

Sha*_*ter 4 c++ containers iterator stl generic-programming

我已经设法绕过一些C++的功能(for_each,映射函数,使用迭代器......)但是用于接收泛型容器和迭代器的模板和函数参数列表的构造仍然无法实现.我有一个实际的例子,我希望有人可以为我说明:

使用以下函数处理传入的std :: vector并构建一个进程的许多数据点/迭代的运行总计:

/* the for-loop method - not very savvy */
void UpdateRunningTotal (int_vec& total, int_vec& data_point) {
  for (int i = 0; i < V_SIZE; i++) {
    total[i] += data_point[i];
  }
}

typedef int_vec std::vector<int>;
int_vec running_total (V_SIZE, 0);  // create a container to hold all the "data points" over many iterations
/* further initialization, and some elaborate loop to create data points */

UpdateRunningTotal (running_total, iteration_data);
/* further processing */
Run Code Online (Sandbox Code Playgroud)

上面的工作,但我宁愿有一个函数,它接受迭代器并执行此求和.更好的是,使用推导类型的通用参数列表而不是指定容器类型,即:

UpdateRunningTotal (iteration_data.begin(), iteration_data.end(), running_total.begin());
Run Code Online (Sandbox Code Playgroud)

我现在真的迷失了,需要一些指导来找到如何定义模板和参数列表以使函数通用.模板和函数定义是什么样的?我已经熟悉使用STL功能执行此特定任务的方法 - 我正在寻找通用功能/模板定义的说明.

GMa*_*ckG 7

你可以使用std::transformstd::plus:

std::transform(iteration_data.begin(), iteration_data.end(),
                running_total.begin(), iteration_data.begin(), std::plus<int>());
Run Code Online (Sandbox Code Playgroud)

在你的功能中,那将是:

template <typename Iter1, typename Iter2>
void UpdateRunningTotal(Iter1 pBegin, Iter1 pEnd, Iter2 pBegin2)
{
    typedef typename std::iterator_traits<Iter1>::value_type value_type;

    std::transform(pBegin, pEnd, pBegin2, pBegin, std::plus<value_type>());
}
Run Code Online (Sandbox Code Playgroud)

  • @Shamster:那么,在我的代码中,`UpdateRunningTotal`是一个"函数模板".记住我们调用函数而不是函数模板,当我们调用`UpdateRunningTotal`时,它需要被"实例化",从而产生一个我们实际调用的函数.为了实例化模板,必须提供所有模板参数.现在,您可以:`UpdateRunningTotal <X,Y>(/*...*/)`并自己填写它们,但这太荒谬了.相反,函数模板将从函数参数"推导"其模板参数.当我们调用它时,为了实例化一个函数... (2认同)
  • ...将推断我们应该将`Iter1`作为`pBegin`的类型,并且`Iter2`应该是`pBegin2`的类型,并将隐式填写这些模板参数.这就是全部,所以函数被实例化.(所以在函数体中,`Iter1`和`Iter2`的类型已经知道了.) (2认同)