当前位置: 首页 > 知识库问答 >
问题:

在模板中奇怪地使用std::accumulate

阳俊德
2023-03-14

我在旧版本的C Cookbook中看到了这段代码,这让我很困惑。这似乎是编译,但我不知道为什么代码会这样写。

T()是什么意思?这是std::accumulate的init参数——开始求和的值。我编写了一个版本,其中我将double()替换为T()(以“硬连线”模板),然后它进行编译。double()是什么意思?

#include <iostream>
#include <numeric> // accumulate
#include <vector>

template<class T, class Iter_T>
void computeAccum(Iter_T first, Iter_T last, T& accum)
{
    accum = std::accumulate(first, last, T()); // Why is init argument equal to T()?
}

int main()
{
    std::vector<double> vd;
    vd.push_back(1.11);
    vd.push_back(2.22);
    vd.push_back(4.44);
    vd.push_back(3.33);
    double sum1;
    std::cout << "Here is the vector:" << std::endl;
    std::vector<double> ::iterator it;
    for (it = vd.begin(); it != vd.end(); ++it) {
        std::cout << *it << std::endl;
    }

    computeAccum2(vd.begin(), vd.end(), sum1);
    std::cout << "Answer: " << sum1 << std::endl;
}

共有2个答案

闻人升
2023-03-14

基本上是零初始化。考虑这个例子来澄清

#include <bits/stdc++.h> 
using namespace std;

int main(){
    cout<<"Int: "<<int()<<endl;
    cout<<"Float: "<<float()<<endl;
    cout<<"String: "<<string();
}

输出:

Int: 0
Float: 0
String: 
姜嘉荣
2023-03-14

这个累加器的变体有三个参数,范围中的第一个和最后一个元素,以及开始时的初始值(下面这个特定的原型是C20的,尽管早期的原型是相似的,只是少了CONSTEXR善):

template< class InputIt, class T >
constexpr T accumulate( InputIt first, InputIt last, T init );

它允许你积累到已经开始的东西。因此,如果将值34累加起来,初始值为22,最终值将为28。这样做的原因是,您可能希望积累一组特定的数据,然后再积累更多的数据。通过使用初始起始值,可以在单个项目中进行多次累加。

在这种情况下,T()只是模板类型的默认构造的初始元素,基本上是您使用的任何类型的“零”值。

 类似资料:
  • 我有困难使用在我的函数,采取可变模板。我开始认为我不需要使用可变模板,但我已经尝试了这么久,我在杂草中思考,需要一个有新面貌的人。 下面的模板函数接受一个常规模板参数,然后接受一个可变参数。它导致编译器错误: 编译器错误: 错误1错误C2664:“状态组件::registerEvent” 这里到底出了什么问题?我如何修复这个编译器错误?

  • 我对火花有点陌生。在我的spark calc完成后,我目前在amazon s3上看到一些奇怪的缓慢的拼花。 写一个小文件需要1.8小时(写时有2个分区) 我用一个不同的更大的文件(更多行更多列)运行了相同的spark calc(编写时有3个分区) 写入调用本身:

  • 我有一个arm模板,可以创建2个文档数据库服务器。ARM模板的部分如下所示: 变量如下所示: 当我运行我的版本时,我得到这个错误(对于两个DocumentDb服务器): 这对我来说毫无意义。我试过用谷歌搜索它,但找不到任何错误的参考。奇怪的是,它创建了资源,并且这些资源是可用的,但部署说它失败了。 以前有人看过这个问题吗?

  • 我试图理解编译器在这里抱怨的原因: 使用编译时生成的消息 如下: cexpr_test.cpp:在函数 'int main()' 中: cexpr_test.cpp:12:76: error: 'const std::initializer_list{((const char* const*)( 令人困惑的是,为什么它会毫无问题地构造第一个初始值设定项列表。我在这里缺少什么?

  • 在我的Fedora 34环境(g)中,定义为: 如果表达式已经是右值,那么

  • 以下代码是尝试使用lodash fp制作我的2048版本(游戏)的开始。我习惯了普通的洛达斯,但这是我第一次接触fp口味。 它使用两个功能实现将一行的瓷砖向右推的操作: 将该行向右推,前提是有空格(由值0表示)。实际上,这相当于把所有的零放在左边。 合并成对的相同值的连续磁贴,生成一个空空间和一个值加倍的新磁贴。(从那一步)。 这些函数使用方法,该方法从右向左遍历磁贴。 似乎工作正常。例如,将转换