Namespaces
Variants

std::ranges:: remove, std::ranges:: remove_if

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
Constrained algorithms
All names in this menu belong to namespace std::ranges
Non-modifying sequence operations
Modifying sequence operations
Partitioning operations
Sorting operations
Binary search operations (on sorted ranges)
Set operations (on sorted ranges)
Heap operations
Minimum/maximum operations
Permutation operations
Fold operations
Operations on uninitialized storage
Return types
헤더 파일에 정의됨 <algorithm>
호출 시그니처
(1)
template < std:: permutable I, std:: sentinel_for < I > S,

class T, class Proj = std:: identity >
requires std:: indirect_binary_predicate
< ranges:: equal_to , std :: projected < I, Proj > , const T * >
constexpr ranges:: subrange < I >

remove ( I first, S last, const T & value, Proj proj = { } ) ;
(C++20부터)
(C++26까지)
template < std:: permutable I, std:: sentinel_for < I > S,

class Proj = std:: identity ,
class T = std :: projected_value_t < I, Proj > >
requires std:: indirect_binary_predicate
< ranges:: equal_to , std :: projected < I, Proj > , const T * >
constexpr ranges:: subrange < I >

remove ( I first, S last, const T & value, Proj proj = { } ) ;
(C++26부터)
(2)
template < ranges:: forward_range R,

class T, class Proj = std:: identity >
requires std:: permutable < ranges:: iterator_t < R >> &&
std:: indirect_binary_predicate
< ranges:: equal_to ,
std :: projected < ranges:: iterator_t < R > , Proj > , const T * >
constexpr ranges:: borrowed_subrange_t < R >

remove ( R && r, const T & value, Proj proj = { } ) ;
(C++20부터)
(C++26까지)
template < ranges:: forward_range R,

class Proj = std:: identity ,
class T = std :: projected_value_t < ranges:: iterator_t < R > , Proj > >
requires std:: permutable < ranges:: iterator_t < R >> &&
std:: indirect_binary_predicate
< ranges:: equal_to ,
std :: projected < ranges:: iterator_t < R > , Proj > , const T * >
constexpr ranges:: borrowed_subrange_t < R >

remove ( R && r, const T & value, Proj proj = { } ) ;
(C++26부터)
template < std:: permutable I, std:: sentinel_for < I > S,

class Proj = std:: identity ,
std:: indirect_unary_predicate < std :: projected < I, Proj >> Pred >
constexpr ranges:: subrange < I >

remove_if ( I first, S last, Pred pred, Proj proj = { } ) ;
(3) (C++20 이후)
template < ranges:: forward_range R,

class Proj = std:: identity ,
std:: indirect_unary_predicate
< std :: projected < ranges:: iterator_t < R > , Proj >> Pred >
requires std:: permutable < ranges:: iterator_t < R >>
constexpr ranges:: borrowed_subrange_t < R >

remove_if ( R && r, Pred pred, Proj proj = { } ) ;
(4) (C++20 이후)

범위 [ first , last ) 에서 특정 조건을 만족하는 모든 요소를 제거하고, [ ret , last ) 부분 범위를 반환합니다. 여기서 ret 는 범위의 새로운 끝을 가리키는 past-the-end iterator입니다.

1) value 와 동일한 모든 요소를 제거하며, 비교를 위해 std:: invoke ( proj, * i ) == value 를 사용합니다.
3) std:: invoke ( pred, std:: invoke ( proj, * i ) ) true 를 반환하는 모든 요소를 제거합니다.
2,4) (1,3) 와 동일하지만, r 을 범위로 사용하며, 마치 ranges:: begin ( r ) first 로, ranges:: end ( r ) last 로 사용하는 것과 같습니다.

제거는 범위 내 요소들을 이동 대입(move assignment)을 통해 이동시킴으로써 수행되며, 제거되지 않을 요소들이 범위의 시작 부분에 나타나도록 합니다. 남아 있는 요소들의 상대적 순서는 유지되며 컨테이너의 물리적 크기는 변경되지 않습니다. 새로운 논리적 끝과 범위의 물리적 끝 사이에 있는 요소를 가리키는 반복자들은 여전히 역참조 가능하지만, 요소 자체는 지정되지 않은 값을 가집니다 ( MoveAssignable 사후 조건에 따름).

이 페이지에서 설명하는 함수형 개체들은 algorithm function objects (일반적으로 niebloids 로 알려진)입니다. 즉:

목차

매개변수

first, last - 처리할 요소들의 범위 를 정의하는 반복자-감시자 쌍
r - 처리할 요소들의 범위
value - 제거할 요소의 값
pred - 투영된 요소들에 적용할 조건자
proj - 요소들에 적용할 투영

반환값

{ ret, last } , 여기서 [ first , ret ) 는 제거 후 결과적인 부분 범위이며, 부분 범위 [ ret , last ) 내의 요소들은 모두 유효하지만 지정되지 않은 상태에 있습니다. 즉, [ ret , last ) 는 삭제될 부분 범위입니다.

복잡도

정확히 N 번의 해당 predicate와 모든 projection이 적용되며, 여기서 N = ranges:: distance ( first, last ) 입니다. 또한 최악의 경우 N - 1 번의 move 연산이 수행됩니다.

참고 사항

ranges::remove 에 대한 호출은 일반적으로 컨테이너의 erase 멤버 함수 호출이 뒤따르며, 이는 지정되지 않은 값을 지우고 컨테이너의 물리적 크기를 새로운 논리적 크기에 맞게 축소합니다. 이 두 가지 호출을 함께 사용하면 소위 erase-remove idiom 이 구성되며, 이는 모든 표준 시퀀스 컨테이너에 대해 오버로드 를 갖는 자유 함수 std::erase 또는 모든 표준 컨테이너에 대해 오버로드 를 갖는 std::erase_if 를 통해 달성할 수 있습니다.

유사한 이름의 컨테이너 멤버 함수 list::remove , list::remove_if , forward_list::remove , 그리고 forward_list::remove_if 는 제거된 요소들을 삭제합니다.

이러한 알고리즘은 일반적으로 std::set std::map 같은 연관 컨테이너와 함께 사용할 수 없습니다. 왜냐하면 이들의 반복자 타입이 MoveAssignable 타입으로 역참조되지 않기 때문입니다(이러한 컨테이너의 키는 수정할 수 없습니다).

ranges::remove value 를 참조로 받기 때문에, 이 값이 범위 [ first , last ) 의 요소를 참조하는 경우 예상치 못한 동작이 발생할 수 있습니다.

가능한 구현

remove (1,2)
struct remove_fn
{
    template<std::permutable I, std::sentinel_for<I> S, class Proj = std::identity,
             class T = std::projected_value_t<I, Proj>>
    requires std::indirect_binary_predicate
                 <ranges::equal_to, std::projected<I, Proj>, const T*>
    constexpr ranges::subrange<I>
        operator()(I first, S last, const T& value, Proj proj = {}) const
    {
        first = ranges::find(std::move(first), last, value, proj);
        if (first != last)
        {
            for (I i{std::next(first)}; i != last; ++i)
                if (value != std::invoke(proj, *i))
                {
                    *first = ranges::iter_move(i);
                    ++first;
                }
        }
        return {first, last};
    }
    template<ranges::forward_range R, class Proj = std::identity,
             class T = std::projected_value_t<ranges::iterator_t<R>, Proj>>
    requires std::permutable<ranges::iterator_t<R>> &&
             std::indirect_binary_predicate
                 <ranges::equal_to,
                  std::projected<ranges::iterator_t<R>, Proj>, const T*>
    constexpr ranges::borrowed_subrange_t<R>
        operator()(R&& r, const T& value, Proj proj = {}) const
    {
        return (*this)(ranges::begin(r), ranges::end(r), value, std::move(proj));
    }
};
inline constexpr remove_fn remove {};
remove_if (3,4)
struct remove_if_fn
{
    template<std::permutable I, std::sentinel_for<I> S, class Proj = std::identity,
             std::indirect_unary_predicate<std::projected<I, Proj>> Pred>
    constexpr ranges::subrange<I>
        operator()(I first, S last, Pred pred, Proj proj = {}) const
    {
        first = ranges::find_if(std::move(first), last, pred, proj);
        if (first != last)
        {
            for (I i{std::next(first)}; i != last; ++i)
                if (!std::invoke(pred, std::invoke(proj, *i)))
                {
                    *first = ranges::iter_move(i);
                    ++first;
                }
        }
        return {first, last};
    }
    template<ranges::forward_range R, class Proj = std::identity,
             std::indirect_unary_predicate
                 <std::projected<ranges::iterator_t<R>, Proj>> Pred>
    requires std::permutable<ranges::iterator_t<R>>
    constexpr ranges::borrowed_subrange_t<R>
        operator()(R&& r, Pred pred, Proj proj = {}) const
    {
        return (*this)(ranges::begin(r), ranges::end(r), pred, std::move(proj));
    }
};
inline constexpr remove_if_fn remove_if {};

참고 사항

기능 테스트 매크로 표준 기능
__cpp_lib_algorithm_default_value_type 202403 (C++26) 목록 초기화 for algorithms ( 1,2 )

예제

#include <algorithm>
#include <cassert>
#include <complex>
#include <cctype>
#include <iomanip>
#include <iostream>
#include <string>
#include <string_view>
#include <vector>
int main()
{
    std::string v1{"진단 불필요"};
    std::cout << std::quoted(v1) << " (v1, 크기: " << v1.size() << ")\n";
    const auto ret = std::ranges::remove(v1, ' ');
    std::cout << std::quoted(v1) << " (v1 after `remove`, size: " << v1.size() << ")\n";
    std::cout << ' ' << std::string(std::distance(v1.begin(), ret.begin()), '^') << '\n';
    v1.erase(ret.begin(), ret.end());
    std::cout << std::quoted(v1) << " (v1 `erase` 이후, 크기: " << v1.size() << ")\n\n";
    // 사용자 정의 단항 조건자를 사용한 remove_if:
    auto rm = [](char c) { return !std::isupper(c); };
    std::string v2{"Substitution Failure Is Not An Error"};
    std::cout << std::quoted(v2) << " (v2, 크기: " << v2.size() << ")\n";
    const auto [first, last] = std::ranges::remove_if(v2, rm);
    std::cout << std::quoted(v2) << " (v2 after `remove_if`, size: " << v2.size() << ")\n";
    std::cout << ' ' << std::string(std::distance(v2.begin(), first), '^') << '\n';
    v2.erase(first, last);
    std::cout << std::quoted(v2) << " (v2 `erase` 이후, 크기: " << v2.size() << ")\n\n";
    // `remove_if`에 의해 수정되는 컨테이너의 뷰 생성:
    for (std::string s : {"Small Object Optimization", "비타입 템플릿 매개변수"})
        std::cout << std::quoted(s) << " => "
            << std::string_view{begin(s), std::ranges::remove_if(s, rm).begin()} << '\n';
    std::vector<std::complex<double>> nums{{2, 2}, {1, 3}, {4, 8}};
    #ifdef __cpp_lib_algorithm_default_value_type
        auto e = std::ranges::remove(nums, {1, 3}); // T가 추론됨
    #else
        auto e = std::ranges::remove(nums, std::complex<double>{1, 3});
    #endif
    nums.erase(e.begin(), e.end());
    assert((nums == std::vector<std::complex<double>>{{2, 2}, {4, 8}}));
}

가능한 출력:

"No _ Diagnostic _ Required" (v1, 크기: 26)
"No_Diagnostic_Requiredired" (v1 `remove` 후, 크기: 26)
 ^^^^^^^^^^^^^^^^^^^^^^
"No_Diagnostic_Required" (v1 `erase` 후, 크기: 22)
"Substitution Failure Is Not An Error" (v2, 크기: 36)
"SFINAEtution Failure Is Not An Error" (v2 `remove_if` 후, 크기: 36)
 ^^^^^^
"SFINAE" (v2 `erase` 후, 크기: 6)
"Small Object Optimization" => SOO
"Non-Type Template Parameter" => NTTP

참고 항목

특정 조건을 만족하는 요소들을 생략하고 범위의 요소들을 복사합니다
(알고리즘 함수 객체)
범위에서 연속된 중복 요소들을 제거합니다
(알고리즘 함수 객체)
특정 조건을 만족하는 요소들을 제거합니다
(함수 템플릿)