Namespaces
Variants

std::transform

より ja.cppreference.net
 
 
アルゴリズムライブラリ
制約付きアルゴリズムと範囲に関するアルゴリズム (C++20)
制約付きアルゴリズム、例 ranges::copy, ranges::sort, ...
変更を加えないシーケンス操作    
一括操作
(C++17)
検索操作
変更を加えるシーケンス操作
コピー操作
(C++11)
(C++11)
スワップ操作
変換操作
生成操作
削除操作
順序変更操作
(C++17まで)(C++11)
(C++20)(C++20)
サンプリング操作
(C++17)

ソートおよび関連操作
分割操作
(C++11)    

ソート操作
二分探索操作
(分割範囲に対して)
集合操作 (ソート済み範囲に対して)
マージ操作 (ソート済み範囲に対して)
ヒープ操作
最小/最大操作
(C++11)
(C++17)
辞書順比較操作
順列操作


 
ヘッダ <algorithm>
template< class InputIt, class OutputIt, class UnaryOp >
OutputIt transform( InputIt first1, InputIt last1,
                    OutputIt d_first, UnaryOp unary_op );
で定義 (1) (constexpr C++20より)
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) (constexpr C++20より)
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 が二つの範囲からの要素のペアに適用される: [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 に従って実行される。
これらのオーバーロードは、以下の式の値が true である場合にのみオーバーロード解決に参加する:

std::is_execution_policy_v<std::decay_t<ExecutionPolicy>>

(C++20まで)

std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>>

(C++20より)

パラメータ

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 は副作用を持つことができなかった 関連する範囲を変更することはできない

関連項目

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