Namespaces
Variants

std:: reduce

From cppreference.net
Algorithm library
Constrained algorithms and algorithms on ranges (C++20)
Constrained algorithms, e.g. ranges::copy , ranges::sort , ...
Execution policies (C++17)
Non-modifying sequence operations
Batch operations
(C++17)
Search operations
Modifying sequence operations
Copy operations
(C++11)
(C++11)
Swap operations
Transformation operations
Generation operations
Removing operations
Order-changing operations
(until C++17) (C++11)
(C++20) (C++20)
Sampling operations
(C++17)

Sorting and related operations
Partitioning operations
Sorting operations
Binary search operations
(on partitioned ranges)
Set operations (on sorted ranges)
Merge operations (on sorted ranges)
Heap operations
Minimum/maximum operations
Lexicographical comparison operations
Permutation operations
C library
Numeric operations
Operations on uninitialized memory
ヘッダーで定義 <numeric>
template < class InputIt >

typename std:: iterator_traits < InputIt > :: value_type

reduce ( InputIt first, InputIt last ) ;
(1) (C++17以降)
(C++20でconstexpr)
template < class ExecutionPolicy, class ForwardIt >

typename std:: iterator_traits < ForwardIt > :: value_type
reduce ( ExecutionPolicy && policy,

ForwardIt first, ForwardIt last ) ;
(2) (C++17以降)
template < class InputIt, class T >
T reduce ( InputIt first, InputIt last, T init ) ;
(3) (C++17以降)
(C++20でconstexpr)
template < class ExecutionPolicy, class ForwardIt, class T >

T reduce ( ExecutionPolicy && policy,

ForwardIt first, ForwardIt last, T init ) ;
(4) (C++17以降)
template < class InputIt, class T, class BinaryOp >
T reduce ( InputIt first, InputIt last, T init, BinaryOp op ) ;
(5) (C++17以降)
(C++20でconstexpr)
template < class ExecutionPolicy,

class ForwardIt, class T, class BinaryOp >
T reduce ( ExecutionPolicy && policy,

ForwardIt first, ForwardIt last, T init, BinaryOp op ) ;
(6) (C++17以降)
1) 次と同等 reduce ( first, last, typename std:: iterator_traits < InputIt > :: value_type { } ) .
3) 次と同等 reduce ( first, last, init, std:: plus <> ( ) ) .
5) 範囲 [ first , last ) を、指定されない方法で並べ替えおよび集約された可能性のある状態で、初期値 init と共に op に対して縮約します。
2,4,6) (1,3,5) と同様ですが、 policy に従って実行されます。
これらのオーバーロードは、以下の全ての条件が満たされる場合にのみオーバーロード解決に参加します:

std:: is_execution_policy_v < std:: decay_t < ExecutionPolicy >> true であること。

(C++20まで)

std:: is_execution_policy_v < std:: remove_cvref_t < ExecutionPolicy >> true であること。

(C++20以降)

実際の二項演算として binary_op が与えられた場合:

  • binary_op が結合的または可換的でない場合(浮動小数点加算など)、結果は非決定的になります。
  • 以下のいずれかの値が T に変換できない場合、プログラムは不適格です:
  • binary_op ( init, * first )
  • binary_op ( * first, init )
  • binary_op ( init, init )
  • binary_op ( * first, * first )
  • 以下のいずれかの条件が満たされる場合、動作は未定義です:
  • T MoveConstructible ではありません。
  • binary_op [ first , last ) の任意の要素を変更します。
  • binary_op [ first , last ] の任意のイテレータまたは部分範囲を無効化します。

目次

パラメータ

first, last - アルゴリズムを適用する要素の 範囲 を定義するイテレータのペア
init - 一般化された合計の初期値
policy - 使用する 実行ポリシー
op - 入力イテレータのデリファレンス結果、他の op の結果、および init に対して未指定の順序で適用される二項 FunctionObject
型要件
-
InputIt LegacyInputIterator の要件を満たさなければならない
-
ForwardIt LegacyForwardIterator の要件を満たさなければならない

戻り値

1-4) init [ first , last ) の要素の一般化された和を std:: plus <> ( ) で計算する。
5,6) init [ first , last ) の要素に対する op による一般化された和。

要素のグループに対する 一般化された総和 は、二項演算 binary_op に対して以下のように定義されます:

  • グループに要素が1つしかない場合、合計はその要素の値です。
  • それ以外の場合、以下の操作を順番に実行します:
  1. グループから任意の2つの要素 elem1 elem2 を取得します。
  2. binary_op ( elem1, elem2 ) を計算し、結果をグループに戻します。
  3. ステップ1と2をグループ内に要素が1つだけになるまで繰り返します。

計算量

与えられた N std:: distance ( first, last ) として:

1-4) O(N) 回の std:: plus <> ( ) 適用。
5,6) O(N) 回の op の適用。

例外

ExecutionPolicy という名前のテンプレートパラメータを持つオーバーロードは、 以下のようにエラーを報告します:

  • アルゴリズムの一部として呼び出された関数の実行が例外をスローした場合、 ExecutionPolicy 標準ポリシー のいずれかであるとき、 std::terminate が呼び出される。それ以外の ExecutionPolicy については、動作は実装定義である。
  • アルゴリズムがメモリの確保に失敗した場合、 std::bad_alloc がスローされる。

注記

std::reduce std::accumulate と同様に動作しますが、範囲の要素が任意の順序でグループ化および再配置される可能性がある点が異なります。

std::reduce std::accumulate の比較:

#if PARALLEL
#include <execution>
#define SEQ std::execution::seq,
#define PAR std::execution::par,
#else
#define SEQ
#define PAR
#endif
#include <chrono>
#include <iomanip>
#include <iostream>
#include <locale>
#include <numeric>
#include <utility>
#include <vector>
int main()
{
    std::cout.imbue(std::locale("en_US.UTF-8"));
    std::cout << std::fixed << std::setprecision(1);
    auto eval = [](auto fun)
    {
        const auto t1 = std::chrono::high_resolution_clock::now();
        const auto [name, result] = fun();
        const auto t2 = std::chrono::high_resolution_clock::now();
        const std::chrono::duration<double, std::milli> ms = t2 - t1;
        std::cout << std::setw(28) << std::left << name << "合計: "
                  << result << '\t' << "時間: " << ms.count() << " ms\n";
    };
    {
        const std::vector<double> v(100'000'007, 0.1);
        eval([&v]{ return std::pair{"std::accumulate (double)",
            std::accumulate(v.cbegin(), v.cend(), 0.0)}; });
        eval([&v]{ return std::pair{"std::reduce (seq, double)",
            std::reduce(SEQ v.cbegin(), v.cend())}; });
        eval([&v]{ return std::pair{"std::reduce (par, double)",
            std::reduce(PAR v.cbegin(), v.cend())}; });
    }
    {
        const std::vector<long> v(100'000'007, 1);
        eval([&v]{ return std::pair{"std::accumulate (long)",
            std::accumulate(v.cbegin(), v.cend(), 0l)}; });
        eval([&v]{ return std::pair{"std::reduce (seq, long)",
            std::reduce(SEQ v.cbegin(), v.cend())}; });
        eval([&v]{ return std::pair{"std::reduce (par, long)",
            std::reduce(PAR v.cbegin(), v.cend())}; });
    }
}

出力例:

// POSIX: g++ -std=c++23 ./example.cpp -ltbb -O3; ./a.out
std::accumulate (double)    合計: 10,000,000.7	時間: 356.9 ms
std::reduce (seq, double)   合計: 10,000,000.7	時間: 140.1 ms
std::reduce (par, double)   合計: 10,000,000.7	時間: 140.1 ms
std::accumulate (long)      合計: 100,000,007	時間: 46.0 ms
std::reduce (seq, long)     合計: 100,000,007	時間: 67.3 ms
std::reduce (par, long)     合計: 100,000,007	時間: 63.3 ms
// POSIX: g++ -std=c++23 ./example.cpp -ltbb -O3 -DPARALLEL; ./a.out
std::accumulate (double)    合計: 10,000,000.7	時間: 353.4 ms
std::reduce (seq, double)   合計: 10,000,000.7	時間: 140.7 ms
std::reduce (par, double)   合計: 10,000,000.7	時間: 24.7 ms
std::accumulate (long)      合計: 100,000,007	時間: 42.4 ms
std::reduce (seq, long)     合計: 100,000,007	時間: 52.0 ms
std::reduce (par, long)     合計: 100,000,007	時間: 23.1 ms

関連項目

要素の範囲を合計または畳み込む
(関数テンプレート)
要素の範囲に関数を適用し、結果を宛先範囲に格納する
(関数テンプレート)
呼び出し可能オブジェクトを適用し、非順序で縮約する
(関数テンプレート)
要素の範囲を左畳み込みする
(アルゴリズム関数オブジェクト)