Namespaces
Variants

std:: transform

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
ヘッダーで定義 <algorithm>
template < class InputIt, class OutputIt, class UnaryOp >

OutputIt transform ( InputIt first1, InputIt last1,

OutputIt d_first, UnaryOp unary_op ) ;
(1) (C++20以降constexpr)
template < class ExecutionPolicy,

class ForwardIt1, class ForwardIt2, class UnaryOp >
ForwardIt2 transform ( ExecutionPolicy && policy,
ForwardIt1 first1, ForwardIt1 last1,

ForwardIt2 d_first, UnaryOp unary_op ) ;
(2) (C++17以降)
template < class InputIt1, class InputIt2,

class OutputIt, class BinaryOp >
OutputIt transform ( InputIt1 first1, InputIt1 last1, InputIt2 first2,

OutputIt d_first, BinaryOp binary_op ) ;
(3) (C++20以降constexpr)
template < class ExecutionPolicy,

class ForwardIt1, class ForwardIt2,
class ForwardIt3, class BinaryOp >
ForwardIt3 transform ( ExecutionPolicy && policy,
ForwardIt1 first1, ForwardIt1 last1,
ForwardIt2 first2,

ForwardIt3 d_first, BinaryOp binary_op ) ;
(4) (C++17以降)

std::transform は、指定された入力範囲の要素に関数を適用し、その結果を d_first から始まる出力範囲に格納します。

1) 単項演算 unary_op [ first1 , last1 ) の要素に適用されます。
もし unary_op が以下のいずれかの範囲内でイテレータを無効化するか、要素を変更する場合、動作は未定義です:
  • [ first1 , last1 ] .
  • std:: distance ( first1, last1 ) + 1 個の要素からなる範囲( d_first から開始)。
3) 二項演算 binary_op は、2つの範囲 [ first1 , last1 ) と、 std:: distance ( first1, last1 ) 個の要素を持つ first2 から始まる別の範囲の要素ペアに適用されます。
もし binary_op が以下のいずれかの範囲でイテレータを無効化するか、要素を変更する場合、動作は未定義です:
  • [ first1 , last1 ] .
  • std:: distance ( first1, last1 ) + 1 個の要素から始まる first2 からの範囲。
  • std:: distance ( first1, last1 ) + 1 個の要素から始まる d_first からの範囲。
2,4) (1,3) と同様ですが、 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以降)

目次

翻訳の説明: - 「Contents」を「目次」に翻訳しました - その他のC++関連の専門用語(Parameters、Return value、Complexity、Exceptions、Possible implementation、Notes、Example、Defect reports、See also)は原文のまま保持しました - HTMLタグ、属性、クラス名、IDなどは一切変更していません - 番号付けや構造は完全に保持されています

パラメータ

first1, last1 - 変換する要素のソース 範囲 を定義するイテレータのペア
first2 - 変換する2番目の要素範囲の先頭 ( 3,4 ) のみ
d_first - 出力先範囲の先頭。 first1 または first2 と等しくてもよい
policy - 使用する 実行ポリシー
unary_op - 適用される単項演算関数オブジェクト

関数のシグネチャは以下と同等であること:

Ret fun ( const Type & a ) ;

シグネチャに const & は必要ない。
Type は、 InputIt 型のオブジェクトが逆参照され、暗黙的に Type に変換可能であること。型 Ret は、 OutputIt 型のオブジェクトが逆参照され、 Ret 型の値を代入可能であること。 ​

binary_op - 適用される二項演算関数オブジェクト

関数のシグネチャは以下と同等であること:

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

シグネチャに const & は必要ない。
Type1 Type2 は、 InputIt1 および InputIt2 型のオブジェクトが逆参照され、暗黙的に Type1 および Type2 に変換可能であること。型 Ret は、 OutputIt 型のオブジェクトが逆参照され、 Ret 型の値を代入可能であること。 ​

型要件
-
InputIt, InputIt1, InputIt2 LegacyInputIterator の要件を満たすこと
-
OutputIt LegacyOutputIterator の要件を満たすこと
-
ForwardIt1, ForwardIt2, ForwardIt3 LegacyForwardIterator の要件を満たすこと

戻り値

変換された最後の要素に続く要素への出力イテレータ。

計算量

与えられた N std:: distance ( first1, last1 ) として:

1,2) 厳密に N 回の unary_op の適用。
3,4) 厳密に N 回の binary_op 適用。

例外

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

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

実装例

transform (1)
template<class InputIt, class OutputIt, class UnaryOp>
constexpr //< since C++20
OutputIt transform(InputIt first1, InputIt last1,
                   OutputIt d_first, UnaryOp unary_op)
{
    for (; first1 != last1; ++d_first, ++first1)
        *d_first = unary_op(*first1);
    return d_first;
}
transform (3)
template<class InputIt1, class InputIt2, 
         class OutputIt, class BinaryOp>
constexpr //< since C++20
OutputIt transform(InputIt1 first1, InputIt1 last1, InputIt2 first2,
                   OutputIt d_first, BinaryOp binary_op)
{
    for (; first1 != last1; ++d_first, ++first1, ++first2)
        *d_first = binary_op(*first1, *first2);
    return d_first;
}

注記

std::transform unary_op または binary_op の順序保証された適用を保証しません。順序を保ってシーケンスに関数を適用する場合、またはシーケンスの要素を変更する関数を適用する場合は、 std::for_each を使用してください。

#include <algorithm>
#include <cctype>
#include <iomanip>
#include <iostream>
#include <string>
#include <utility>
#include <vector>
void print_ordinals(const std::vector<unsigned>& ordinals)
{
    std::cout << "ordinals: ";
    for (unsigned ord : ordinals)
        std::cout << std::setw(3) << ord << ' ';
    std::cout << '\n';
}
char to_uppercase(unsigned char c)
{
    return std::toupper(c);
}
void to_uppercase_inplace(char& c)
{
    c = to_uppercase(c);
}
void unary_transform_example(std::string& hello, std::string world)
{
    // 文字列を大文字に変換(インプレース)
    std::transform(hello.cbegin(), hello.cend(), hello.begin(), to_uppercase);
    std::cout << "hello = " << std::quoted(hello) << '\n';
    // for_each バージョン(上記の注記を参照)
    std::for_each(world.begin(), world.end(), to_uppercase_inplace);
    std::cout << "world = " << std::quoted(world) << '\n';
}
void binary_transform_example(std::vector<unsigned> ordinals)
{
    // 数値を2倍の値に変換
    print_ordinals(ordinals);
    std::transform(ordinals.cbegin(), ordinals.cend(), ordinals.cbegin(),
                   ordinals.begin(), std::plus<>{});
    print_ordinals(ordinals);
}
int main()
{
    std::string hello("hello");
    unary_transform_example(hello, "world");
    std::vector<unsigned> ordinals;
    std::copy(hello.cbegin(), hello.cend(), std::back_inserter(ordinals));
    binary_transform_example(std::move(ordinals));
}

出力:

hello = "HELLO"
world = "WORLD"
ordinals:  72  69  76  76  79 
ordinals: 144 138 152 152 158

不具合報告

以下の動作変更の欠陥報告書は、以前に公開されたC++規格に対して遡及的に適用されました。

DR 適用対象 公開時の動作 正しい動作
LWG 242 C++98 unary_op および binary_op は副作用を持つことができなかった 関連する範囲を変更することはできない

関連項目

単項 関数オブジェクト 範囲 の要素に適用する
(関数テンプレート)
要素の範囲に関数を適用する
(アルゴリズム関数オブジェクト)