Movatterモバイル変換


[0]ホーム

URL:


cppreference.com
Namespaces
Variants
    Actions

      std::adjacent_difference

      From cppreference.com
      <cpp‎ |algorithm
       
       
      Algorithm library
      Constrained algorithms and algorithms on ranges(C++20)
      Constrained algorithms, e.g.ranges::copy,ranges::sort, ...
      Execution policies(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
      (C++11)
      (C++17)
      Lexicographical comparison operations
      Permutation operations
      C library
      Numeric operations
      (C++11)
      adjacent_difference
        
      Operations on uninitialized memory
       
       
      Defined in header<numeric>
      template<class InputIt,class OutputIt>

      OutputIt adjacent_difference( InputIt first, InputIt last,

                                    OutputIt d_first);
      (1)(constexpr since C++20)
      template<class ExecutionPolicy,

               class ForwardIt1,class ForwardIt2>
      ForwardIt2 adjacent_difference( ExecutionPolicy&& policy,
                                      ForwardIt1 first, ForwardIt1 last,

                                      ForwardIt2 d_first);
      (2)(since C++17)
      template<class InputIt,class OutputIt,class BinaryOp>

      OutputIt adjacent_difference( InputIt first, InputIt last,

                                    OutputIt d_first, BinaryOp op);
      (3)(constexpr since C++20)
      template<class ExecutionPolicy,

               class ForwardIt1,class ForwardIt2,class BinaryOp>
      ForwardIt2 adjacent_difference( ExecutionPolicy&& policy,
                                      ForwardIt1 first, ForwardIt1 last,

                                      ForwardIt2 d_first, BinaryOp op);
      (4)(since C++17)

      LetT be the value type ofdecltype(first).

      1) If[firstlast) is empty, does nothing.
      Otherwise, performs the following operations in order:
      1. Creates an accumulatoracc of typeT, and initializes it with*first.
      2. Assignsacc to*d_first.
      3. For each iteratoriter in[++firstlast) in order, performs the following operations in order:
      a) Creates an objectval of typeT, and initializes it with*iter.
      b) Computesval- acc(until C++20)val- std::move(acc)(since C++20).
      c) Assigns the result to*++d_first.
      d)Copy(until C++20)Move(since C++20) assigns fromval toacc.
      2) If[firstlast) is empty, does nothing.
      Otherwise, performs the following operations in order:
      1. Assigns*first to*d_first.
      2. For each integeri in[1std::distance(first, last)), performs the following operations in order:
      a) Computescurr- prev, wherecurr is the nextith iterator offirst, andprev is the nexti-1th iterator offirst.
      b) Assigns the result to*dest, wheredest is the nextith iterator ofd_first.
      3) Same as(1), but computesop(val, acc)(until C++20)op(val, std::move(acc))(since C++20) instead.
      4) Same as(2), but computesop(curr, prev) instead.

      Givenbinary_op as the actual binary operation:

      • If any of the following conditions is satisfied, the program is ill-formed:
      • For overloads(1,3):
      • T is not constructible from*first.
      • acc is notwritable tod_first.
      • The result ofbinary_op(val, acc)(until C++20)binary_op(val, std::move(acc))(since C++20) is not writable tod_first.
      • For overloads(2,4):
      • *first is not writable tod_first.
      • The result ofbinary_op(*first,*first) is not writable tod_first.
      • Givend_last as the iterator to bereturned, if any of the following conditions is satisfied, the behavior is undefined:
      (since C++20)
      • For overloads(2,4),[firstlast) and[d_firstd_last) overlaps.
      • binary_op modifies any element of[firstlast) or[d_firstd_last).
      • binary_op invalidates any iterator or subrange in[firstlast] or[d_firstd_last].

      Contents

      [edit]Parameters

      first, last - the pair of iterators defining therange of elements to
      d_first - the beginning of the destination range
      policy - theexecution policy to use
      op - binary operation function object that will be applied.

      The signature of the function should be equivalent to the following:

       Ret fun(const Type1&a,const Type2&b);

      The signature does not need to haveconst&.
      The types Type1 and Type2 must be such that an object of typeiterator_traits<InputIt>::value_type can be implicitly converted to both of them. The typeRet must be such that an object of typeOutputIt can be dereferenced and assigned a value of typeRet.​

      Type requirements
      -
      InputIt must meet the requirements ofLegacyInputIterator.
      -
      OutputIt must meet the requirements ofLegacyOutputIterator.
      -
      ForwardIt1, ForwardIt2 must meet the requirements ofLegacyForwardIterator.

      [edit]Return value

      Iterator to the element past the last element written, ord_first if[firstlast) is empty.

      [edit]Complexity

      Given\(\scriptsize N\)N asstd::distance(first, last):

      1,2) Exactly\(\scriptsize N-1\)N-1 applications ofoperator-.
      3,4) Exactly\(\scriptsize N-1\)N-1 applications of the binary functionop.

      [edit]Exceptions

      The overloads with a template parameter namedExecutionPolicy report errors as follows:

      • If execution of a function invoked as part of the algorithm throws an exception andExecutionPolicy is one of thestandard policies,std::terminate is called. For any otherExecutionPolicy, the behavior is implementation-defined.
      • If the algorithm fails to allocate memory,std::bad_alloc is thrown.

      [edit]Possible implementation

      adjacent_difference (1)
      template<class InputIt,class OutputIt>constexpr// since C++20OutputIt adjacent_difference(InputIt first, InputIt last, OutputIt d_first){if(first== last)return d_first; typedeftypenamestd::iterator_traits<InputIt>::value_type value_t;    value_t acc=*first;*d_first= acc; while(++first!= last){        value_t val=*first;*++d_first= val- std::move(acc);// std::move since C++20        acc= std::move(val);} return++d_first;}
      adjacent_difference (3)
      template<class InputIt,class OutputIt,class BinaryOp>constexpr// since C++20OutputIt adjacent_difference(InputIt first, InputIt last,                              OutputIt d_first, BinaryOp op){if(first== last)return d_first; typedeftypenamestd::iterator_traits<InputIt>::value_type value_t;    value_t acc=*first;*d_first= acc; while(++first!= last){        value_t val=*first;*++d_first= op(val, std::move(acc));// std::move since C++20        acc= std::move(val);} return++d_first;}

      [edit]Notes

      acc was introduced because of the resolution ofLWG issue 539. The reason of usingacc rather than directly calculating the differences is because the semantic of the latter is confusing if the following types mismatch:

      • the value type ofInputIt
      • the writable type(s) ofOutputIt
      • the types of the parameters ofoperator- orop
      • the return type ofoperator- orop

      acc serves as the intermediate object to cache values of the iterated elements:

      • its type is the value type ofInputIt
      • the value written tod_first (which is the return value ofoperator- orop) is assigned to it
      • its value is passed tooperator- orop
      char i_array[4]={100,100,100,100};int  o_array[4]; // OK: performs conversions when needed// 1. creates “acc” of type char (the value type)// 2. “acc” is assigned to the first element of “o_array”// 3. the char arguments are used for long multiplication (char -> long)// 4. the long product is assigned to the output range (long -> int)// 5. the next value of “i_array” is assigned to “acc”// 6. go back to step 3 to process the remaining elements in the input rangestd::adjacent_difference(i_array, i_array+4, o_array,std::multiplies<long>{});

      [edit]Example

      Run this code
      #include <array>#include <functional>#include <iostream>#include <iterator>#include <numeric>#include <vector> void println(auto comment,constauto& sequence){std::cout<< comment;for(constauto& n: sequence)std::cout<< n<<' ';std::cout<<'\n';}; int main(){// Default implementation - the difference between two adjacent itemsstd::vector v{4,6,9,13,18,19,19,15,10};    println("Initially, v = ", v);    std::adjacent_difference(v.begin(), v.end(), v.begin());    println("Modified v = ", v); // Fibonaccistd::array<int,10> a{1};    std::adjacent_difference(std::begin(a),std::prev(std::end(a)),std::next(std::begin(a)),std::plus<>{});    println("Fibonacci, a = ", a);}

      Output:

      Initially, v = 4 6 9 13 18 19 19 15 10 Modified v = 4 2 3 4 5 1 0 -4 -5 Fibonacci, a = 1 1 2 3 5 8 13 21 34 55

      [edit]Defect reports

      The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

      DRApplied toBehavior as publishedCorrect behavior
      LWG 242C++98op could not have side effectsit cannot modify
      the ranges involved
      LWG 539C++98the type requirements needed for the result
      evaluations and assignments to be valid were missing
      added
      LWG 3058C++17for overloads(2,4), the result of each invocation
      ofoperator- orop was assigned to a temporary
      object, and that object is assigned to the output range
      assign the results
      to the output
      range directly

      [edit]See also

      computes the partial sum of a range of elements
      (function template)[edit]
      sums up or folds a range of elements
      (function template)[edit]
      Retrieved from "https://en.cppreference.com/mwiki/index.php?title=cpp/algorithm/adjacent_difference&oldid=180317"

      [8]ページ先頭

      ©2009-2025 Movatter.jp