Namespaces
Variants

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

From cppreference.net
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 - 투영된 요소들에 적용할 predicate
proj - 요소들에 적용할 projection

반환값

다음 두 멤버를 포함하는 tagged_pair 객체:

  • 첫 번째 멤버는 태그 tag::in 를 가지며, 소스 범위의 past-the-end 반복자입니다 (즉, 센티널 last 와 비교 시 동일한 것으로 판단되는 I 타입의 반복자입니다).
  • 두 번째 멤버는 태그 tag::out 를 가지며, 결과 범위의 past-the-end 반복자입니다.

복잡도

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를 사용하여 한 벡터의 내용을 다른 벡터로 복사하고 결과 벡터를 출력합니다:

#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

참고 항목

요소 범위를 새로운 위치로 복사합니다
(함수 템플릿)
요소 범위를 역순으로 복사합니다
(함수 템플릿)
역순으로 된 범위의 복사본을 생성합니다
(함수 템플릿)
지정된 개수의 요소를 새로운 위치로 복사합니다
(함수 템플릿)
요소 범위에 특정 값을 할당합니다
(함수 템플릿)
특정 조건을 만족하는 요소를 제외하고 요소 범위를 복사합니다
(함수 템플릿)