名前空間
変種
操作

std::experimental::ranges::copy、std::experimental::ranges::copy_if

From cppreference.com
< cpp‎ | experimental‎ | ranges
 
 
 
 
 
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)

ソース範囲([firstlast)またはr)の要素を、ソース範囲の最初の要素から最後の要素まで、resultで始まる宛先範囲にコピーします。

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

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

目次

[編集] パラメータ

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

[編集] 戻り値

以下の2つのメンバーを含むtagged_pairオブジェクト

  • 最初のメンバー(タグ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};
}
2番目のバージョン
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);
}
第3版
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};
}
4番目のバージョン
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を使用して、一方のベクターの内容をもう一方のベクターにコピーし、結果のベクターを表示します。

#include <experimental/ranges/algorithm>
#include <experimental/ranges/iterator>
#include <iostream>
#include <numeric>
#include <vector>
 
int main()
{
    // see https://ja.cppreference.dev/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

[編集] 関連項目

要素の範囲を新しい場所にコピーする
(関数テンプレート) [編集]
要素の範囲を逆順にコピーする
(function template) [編集]
逆順になった範囲のコピーを作成する
(function template) [編集]
指定された数の要素を新しい場所にコピーする
(function template) [編集]
要素の範囲に特定の値を代入する
(function template) [編集]
特定の基準を満たす要素を除外して範囲をコピーする
(function template) [編集]
English 日本語 中文(简体) 中文(繁體)