c++20 新特性(1) inner_product

之所以开这一个板块,主要是为了区别c和c++,很多人学了很久c++,但是除了cout之外似乎什么都不懂,只有熟练掌握了这些新特性,才能成为一名合格的c++ programmer

当然,一些常见的新特性,网上千篇一律,我就不赘述了,请读者自己去网上查阅,主要记录一些相对少见但是很有用的新特性。

目录

头文件:

 版本1:

版本2


头文件:

#include <numeric>

 版本1:

template <class InputIterator1, class InputIterator2, class T>
   T inner_product (InputIterator1 first1, InputIterator1 last1,
                    InputIterator2 first2, T init);

涉及泛型编程,传入参数一共有4个,

参数  说明
first1第一个容器的某一个迭代器
last1第一个容器的某一个迭代器,在first后面
first2                        第二个容器的某一个迭代器
init初始值

作用:将first1到last1之间的对象(左闭右开),与first2及其对应位置的对象相乘,并且加上init

template<class InputIt1, class InputIt2, class T>
constexpr//根据有没有分成俩版本
T inner_product(InputIt1 first1, InputIt1 last1,
                InputIt2 first2, T init)
{
    while (first1 != last1) {
         init = std::move(init) + *first1 * *first2;
         ++first1;
         ++first2;
    }
    return init;
}

经过本人实验,其实不需要传入的一定是迭代器,就普通数组的指针也是可以识别的,只要能够进行左加操作以及解引用,都可以正常使用,不过为了显得更c++一点,我们还是尽量用迭代器

例1

// inner_product example
#include <iostream>     // std::cout
#include <functional>   // std::minus, std::divides
#include <numeric>      // std::inner_product

int main () {
  int init = 100;
  int series1[] = {10,20,30};
  int series2[] = {1,2,3};

  std::cout << "using default inner_product: ";
  std::cout << std::inner_product(series1,series1+3,series2,init);
  std::cout << '\n';
  return 0;
}

输出为:

using default inner_product: 240

换成自带的容器,结果一样,

#include <iostream>     // std::cout
#include <functional>   // std::minus, std::divides
#include <numeric>      // std::inner_product
#include <vector>
int main () {
  int init = 100;
  std::vector<int> series1 = {10,20,30};
  std::vector<int> series2 = {1,2,3};

  std::cout << "using default inner_product: ";
  std::cout << std::inner_product(std::begin(series1),std::end(series1),std::begin(series2),init);
  std::cout << '\n';
  return 0;
}

如果first2长度不够,会提前结束,first1同理

#include <iostream>     // std::cout
#include <functional>   // std::minus, std::divides
#include <numeric>      // std::inner_product
#include <vector>
int main () {
  int init = 100;
  std::vector<int> series1 = {10,20,30};
  std::vector<int> series2 = {1,2};

  std::cout << "using default inner_product: ";
  std::cout << std::inner_product(std::begin(series1),std::end(series1),std::begin(series2),init);
  std::cout << '\n';
  return 0;
}

输出为

using default inner_product: 150

版本2

template <class InputIterator1, class InputIterator2, class T,
          class BinaryOperation1, class BinaryOperation2>
   T inner_product (InputIterator1 first1, InputIterator1 last1,
                    InputIterator2 first2, T init,
                    BinaryOperation1 binary_op1,
                    BinaryOperation2 binary_op2);

除了上面四个输入参数外,还多了两个二元可调用对象,

关于c++对可调用对象的定义请读者自行查阅,c++本身也有很多可调用对象,当然,包装器也是可以的。

  1. 第一个op1是对init最后返回结果的操作,版本1中默认为+
  2. 第二个op2是对内积操作的自定义,版本1中默认为乘
template<class InputIt1, class InputIt2,
         class T,
         class BinaryOperation1, class BinaryOperation2>
constexpr //俩版本
T inner_product(InputIt1 first1, InputIt1 last1,
                InputIt2 first2, T init,
                BinaryOperation1 op1
                BinaryOperation2 op2)
{
    while (first1 != last1) {
         init = op1(std::move(init), op2(*first1, *first2)); // std::move since C++20
         ++first1;
         ++first2;
    }
    return init;
}

c++本身提供这些二元可调用对象:

例1:我们把加减乘除换位:

#include <iostream>     // std::cout
#include <functional>   // std::minus, std::divides
#include <numeric>      // std::inner_product
#include <vector>
int main () {
  int init = 100;
  std::vector<int> series1 = {10,20,30};
  std::vector<int> series2 = {1,2,3};

  std::cout << "using functional operations: ";
  std::cout << std::inner_product(std::begin(series1),std::end(series1),std::begin(series2),init,
                                  std::minus<int>(),std::divides<int>());
  std::cout << '\n';
  return 0;
}

结果为:

using functional operations: 70

 例2:

我们用包装器换一下:

// inner_product example
#include <iostream>     // std::cout
#include <functional>   // std::minus, std::divides
#include <numeric>      // std::inner_product
#include <vector>
int myaccumulator (int x, int y) {return x-y;}
int myproduct (int x, int y) {return x+y;}
int main () {
  int init = 100;
  std::vector<int> series1 = {10,20,30};
  std::vector<int> series2 = {1,2,3};
  std::function<int(int,int)>mysub=myaccumulator;
  std::function<int(int,int)>myadd=myproduct;
  std::cout << "using custom functions: ";
  std::cout << std::inner_product(std::begin(series1),std::end(series1),std::begin(series2),init,
                                  mysub,myadd);
  std::cout << '\n';
  return 0;
}

输出为:

using custom functions: 34

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

无情の学习机器

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值