Namespaces
Variants

std::experimental::ranges:: copy, std::experimental::ranges:: copy_if

From cppreference.net
HTMLタグ、属性、C++固有の用語、コード内のテキストは翻訳せず、元のフォーマットを保持しています。 HTMLタグ、属性、C++コード、C++専門用語はすべて原文のまま保持されています。テキスト部分のみが日本語に翻訳されています。 (注:このHTML要素には翻訳対象のテキストコンテンツが含まれていないため、元の構造を保持したまま出力します)
template < InputIterator I, Sentinel < I > S, WeaklyIncrementable O >

requires IndirectlyCopyable < I, O >
ranges:: tagged_pair < tag:: in ( I ) , tag:: out ( O ) >

copy ( I first, S last, O result ) ;
(1) (ranges TS)
template < InputRange R, WeaklyIncrementable O >

requires IndirectlyCopyable < ranges:: iterator_t < R > , O >
ranges:: tagged_pair < tag:: in ( ranges:: safe_iterator_t < R > ) , tag:: out ( O ) >

copy ( R && r, O result ) ;
(2) (ranges TS)
template < InputIterator I, Sentinel < I > S, WeaklyIncrementable O,

class Proj = ranges:: identity ,
IndirectUnaryPredicate < projected < I, Proj >> Pred >
requires IndirectlyCopyable < I, O >
ranges:: tagged_pair < tag:: in ( I ) , tag:: out ( O ) >

copy_if ( I first, S last, O result, Pred pred, Proj proj = Proj { } ) ;
(3) (ranges TS)
template < InputRange R, WeaklyIncrementable O,

class Proj = ranges:: identity ,
IndirectUnaryPredicate < projected < ranges:: iterator_t < R > , Proj >> Pred >
requires IndirectlyCopyable < iterator_t < R > , O >
ranges:: tagged_pair < tag:: in ( ranges:: safe_iterator_t < R > ) , tag:: out ( O ) >

copy_if ( R && r, O result, Pred pred, Proj proj = Proj { } ) ;
(4) (ranges TS)

ソース範囲( [ first , last ) または r )の要素を、ソース範囲の最初の要素から最後の要素に向かって順に、 result を先頭とする宛先範囲にコピーします。

1) 範囲 [ first , last ) 内の全要素をコピーします。各非負整数 n < (last - first) に対して、 * ( result + n ) = * ( first + n ) を実行します。 result が範囲 [ first , last ) 内にある場合の動作は未定義です。この場合、代わりに ranges::copy_backward を使用できます。
2) (1) と同じですが、 r をソース範囲として使用します。以下のように動作します: ranges:: copy ( ranges:: begin ( r ) , ranges:: end ( r ) , result ) ; ただし、 result はコピーされない可能性があります。
3) 投影関数 proj によって要素の値に適用された際に、述語 pred true を返す要素のみをコピーします。コピーされる要素の順序は保持されます。ソース範囲と宛先範囲が重なっている場合の動作は未定義です。
4) (3) と同様だが、 r をソース範囲として使用する。以下のように動作する: ranges:: copy_if ( ranges:: begin ( r ) , ranges:: end ( r ) , result, pred, proj ) ; ただし、 result pred および proj はコピーされない可能性がある。

上記に示された宣言にもかかわらず、アルゴリズム宣言の実際のテンプレートパラメータの数と順序は未規定です。したがって、アルゴリズムを呼び出す際に明示的なテンプレート引数を使用する場合、プログラムはおそらく移植性がありません。

目次

パラメータ

first, last - コピーする要素の範囲
r - コピーする要素の範囲
result - コピー先範囲の先頭
pred - 投影された要素に適用する述語
proj - 要素に適用する投影

戻り値

A tagged_pair オブジェクトは以下の2つのメンバーを含みます:

  • 最初のメンバーはタグ tag::in を持ち、ソース範囲の終端イテレータ(つまり、センチネル last と等価と比較される型 I のイテレータ)です。
  • 2番目のメンバーはタグ tag::out を持ち、結果範囲の終端イテレータです。

計算量

1) 厳密に ranges:: distance ( first, last ) 回の代入。
2) 厳密に ranges:: distance ( r ) 回の代入。
3) 対応する射影と述語の適用を ranges:: distance ( first, last ) 回正確に実行します。
4) 対応する射影と述語の適用を ranges:: distance ( r ) 回正確に行う。

実装例

第一バージョン
template<InputIterator I, Sentinel<I> S, WeaklyIncrementable O>
    requires IndirectlyCopyable<I, O>()
ranges::tagged_pair<tag::in(I), tag::out(O)>
    copy(I first, S last, O result)
{
    for (; first != last; ++first, (void)++result)
        *result = *first;
    return {first, result};
}
第二バージョン
template<InputRange R, WeaklyIncrementable O>
    requires IndirectlyCopyable<ranges::iterator_t<R>, O>()
ranges::tagged_pair<tag::in(ranges::safe_iterator_t<R>), tag::out(O)>
    copy(R&& r, O result)
{
   return ranges::copy(ranges::begin(r), ranges::end(r), result);
}
第三バージョン
template<InputIterator I, Sentinel<I> S, WeaklyIncrementable O,
         class Proj = ranges::identity,
         IndirectUnaryPredicate<projected<I, Proj>> Pred>
    requires IndirectlyCopyable<I, O>()
ranges::tagged_pair<tag::in(I), tag::out(O)>
    copy_if(I first, S last, O result, Pred pred, Proj proj = Proj{})
{
    for (; first != last; ++first)
        if (ranges::invoke(pred, ranges::invoke(proj, *first)))
        {
            *result = *first;
            ++result;
        }
    return {first, result};
}
第四バージョン
template<InputRange R, WeaklyIncrementable O,
         class Proj = ranges::identity,
         IndirectUnaryPredicate<projected<ranges::iterator_t<R>, Proj>> Pred>
    requires IndirectlyCopyable<ranges::iterator_t<R>, O>()
ranges::tagged_pair<tag::in(ranges::safe_iterator_t<R>), tag::out(O)>
    copy_if(R&& r, O result, Pred pred, Proj proj = Proj{})
{
    return ranges::copy_if(ranges::begin(r), ranges::end(r), result, pred, proj);
}

以下のコードは、copyを使用して1つのベクターの内容を別のベクターにコピーし、結果のベクターを表示します:

#include <experimental/ranges/algorithm>
#include <experimental/ranges/iterator>
#include <iostream>
#include <numeric>
#include <vector>
int main()
{
    // see https://en.cppreference.net/w/cpp/language/namespace_alias
    namespace ranges = std::experimental::ranges;
    std::vector<int> from_vector(10);
    std::iota(from_vector.begin(), from_vector.end(), 0);
    std::vector<int> to_vector;
    ranges::copy_if(from_vector.begin(), from_vector.end(),
                    ranges::back_inserter(to_vector),
                    [](const auto i)
                    {
                       return i % 3;
                    });
// or, alternatively,
//  std::vector<int> to_vector(from_vector.size());
//  std::copy(from_vector, to_vector.begin());
    std::cout << "to_vector contains: ";
    ranges::copy(to_vector, ranges::ostream_iterator<int>(std::cout, " "));
    std::cout << '\n';
}

出力:

to_vector contains: 1 2 4 5 7 8

関連項目

要素の範囲を新しい場所にコピーする
(関数テンプレート)
要素の範囲を逆順にコピーする
(関数テンプレート)
逆順にされた範囲のコピーを作成する
(関数テンプレート)
指定された数の要素を新しい場所にコピーする
(関数テンプレート)
要素の範囲に特定の値を代入する
(関数テンプレート)
特定の条件を満たす要素を除外して範囲をコピーする
(関数テンプレート)