Namespaces
Variants

std:: remove, std:: 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
remove remove_if
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
헤더 파일에 정의됨 <algorithm>
(1)
template < class ForwardIt, class T >
ForwardIt remove ( ForwardIt first, ForwardIt last, const T & value ) ;
(C++20부터 constexpr)
(C++26까지)
template < class ForwardIt, class T = typename std:: iterator_traits

< ForwardIt > :: value_type >
constexpr ForwardIt remove ( ForwardIt first, ForwardIt last,

const T & value ) ;
(C++26부터)
(2)
template < class ExecutionPolicy, class ForwardIt, class T >

ForwardIt remove ( ExecutionPolicy && policy,

ForwardIt first, ForwardIt last, const T & value ) ;
(C++17부터)
(C++26까지)
template < class ExecutionPolicy, class ForwardIt,

class T = typename std:: iterator_traits
< ForwardIt > :: value_type >
ForwardIt remove ( ExecutionPolicy && policy,

ForwardIt first, ForwardIt last, const T & value ) ;
(C++26부터)
template < class ForwardIt, class UnaryPred >
ForwardIt remove_if ( ForwardIt first, ForwardIt last, UnaryPred p ) ;
(3) (C++20부터 constexpr)
template < class ExecutionPolicy, class ForwardIt, class UnaryPred >

ForwardIt remove_if ( ExecutionPolicy && policy,

ForwardIt first, ForwardIt last, UnaryPred p ) ;
(4) (C++17부터)

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

1) value 와 동일한 모든 요소를 제거합니다 (using operator == ).
3) 술어 p true 를 반환하는 모든 요소를 제거합니다.
2,4) (1,3) 와 동일하지만, policy 에 따라 실행됩니다.
다음 모든 조건이 만족될 때만 이 오버로드들이 오버로드 해결에 참여합니다:

std:: is_execution_policy_v < std:: decay_t < ExecutionPolicy >> true 입니다.

(C++20 이전)

std:: is_execution_policy_v < std:: remove_cvref_t < ExecutionPolicy >> true 입니다.

(C++20 이후)


ForwardIt 값 타입 CopyAssignable 이 아닌 경우, 동작은 정의되지 않습니다.

(C++11 이전)

* first 의 타입이 MoveAssignable 이 아닌 경우, 동작은 정의되지 않습니다.

(C++11 이후)

목차

설명

제거는 범위 내 요소들을 이동시켜서 제거되지 않을 요소들이 범위의 시작 부분에 나타나도록 하는 방식으로 수행됩니다.

  • 시프팅은 copy assignment (until C++11) move assignment (since C++11) 에 의해 수행됩니다.
  • 제거 연산은 안정적입니다: 제거되지 않는 요소들의 상대적 순서는 유지됩니다.
  • [ first , last ) 의 기저 시퀀스는 제거 연산에 의해 단축되지 않습니다. 반환된 반복자로 result 가 주어집니다:
  • [ result , last ) 범위 내의 모든 반복자는 여전히 역참조 가능 합니다.
  • [ result , last ) 범위의 각 요소는 유효하지만 지정되지 않은 상태를 가지며, 이는 이동 할당이 원래 해당 범위에 있던 요소들로부터 이동하여 요소들을 제거할 수 있기 때문입니다.
(C++11부터)

매개변수

first, last - 처리할 요소들의 범위 를 정의하는 반복자 쌍
value - 제거할 요소의 값
policy - 사용할 실행 정책
p - 요소가 제거되어야 할 경우 ​ true 를 반환하는 단항 predicate.

표현식 p ( v ) VT 타입의 (const 가능성 있는) 모든 인수 v 에 대해 bool 로 변환 가능해야 하며, 값 범주 와 관계없이 v 를 수정해서는 안 됩니다. 따라서 VT & 매개변수 타입은 허용되지 않으며 , VT 에 대해 이동이 복사와 동등하지 않는 한 VT 도 허용되지 않습니다 (C++11부터) . ​

타입 요구사항
-
ForwardIt LegacyForwardIterator 요구사항을 충족해야 합니다.
-
UnaryPredicate Predicate 요구사항을 충족해야 합니다.

반환값

새로운 값 범위의 끝 다음(past-the-end) 반복자 (이것이 end 가 아니라면, 이 반복자는 지정되지 않은 값을 가리키며, 이 반복자와 end 사이의 모든 값에 대한 반복자들도 마찬가지입니다).

복잡도

주어진 N std:: distance ( first, last ) 인 경우:

1,2) 정확히 N 번의 비교를 operator == 를 사용하여 수행합니다.
3,4) 정확히 N 번의 predicate p 적용.

예외

ExecutionPolicy 라는 템플릿 매개변수를 사용하는 오버로드는 다음과 같이 오류를 보고합니다:

  • 알고리즘의 일부로 호출된 함수 실행 중 예외가 발생하고 ExecutionPolicy 표준 정책 중 하나인 경우, std::terminate 가 호출됩니다. 다른 ExecutionPolicy 의 경우 동작은 구현에 따라 정의됩니다.
  • 알고리즘이 메모리 할당에 실패하는 경우, std::bad_alloc 이 throw됩니다.

가능한 구현

remove (1)
template<class ForwardIt, class T = typename std::iterator_traits<ForwardIt>::value_type>
ForwardIt remove(ForwardIt first, ForwardIt last, const T& value)
{
    first = std::find(first, last, value);
    if (first != last)
        for (ForwardIt i = first; ++i != last;)
            if (!(*i == value))
                *first++ = std::move(*i);
    return first;
}
remove_if (3)
template<class ForwardIt, class UnaryPred>
ForwardIt remove_if(ForwardIt first, ForwardIt last, UnaryPred p)
{
    first = std::find_if(first, last, p);
    if (first != last)
        for (ForwardIt i = first; ++i != last;)
            if (!p(*i))
                *first++ = std::move(*i);
    return first;
}

참고 사항

remove 에 대한 호출은 일반적으로 컨테이너의 erase 멤버 함수 호출이 뒤따라 컨테이너에서 실제로 요소를 제거합니다. 이 두 호출을 함께 사용하는 것을 소위 erase-remove idiom (지우기-제거 관용구)라고 합니다.

동일한 효과는 다음 비멤버 함수들을 통해서도 달성할 수 있습니다:

(C++20부터)

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

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

표준 라이브러리는 또한 std::remove 의 오버로드를 <cstdio> 에 정의하고 있으며, 이는 const char * 를 인수로 받아 파일을 삭제하는 데 사용됩니다.

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

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

예제

다음 코드는 모든 공백을 문자열에서 제거하기 위해 공백이 아닌 문자들을 왼쪽으로 이동시킨 후 여분을 지웁니다. 이것은 erase-remove idiom 의 예시입니다.

#include <algorithm>
#include <cassert>
#include <cctype>
#include <complex>
#include <iomanip>
#include <iostream>
#include <string>
#include <string_view>
#include <vector>
int main()
{
    std::string str1{"Quick  Red  Dog"};
    std::cout << "1) " << std::quoted(str1) << '\n';
    const auto noSpaceEnd = std::remove(str1.begin(), str1.end(), ' ');
    std::cout << "2) " << std::quoted(str1) << '\n';
    // 공백들은 논리적으로만 문자열에서 제거됩니다.
    // 참고: 우리는 뷰를 사용하며, 원본 문자열은 아직 축소되지 않았습니다:
    std::cout << "3) " << std::quoted(std::string_view(str1.begin(), noSpaceEnd))
              << ", size: " << str1.size() << '\n';
    str1.erase(noSpaceEnd, str1.end());
    // 공백들이 물리적으로 문자열에서 제거됩니다.
    std::cout << "4) " << std::quoted(str1) << ", size: " << str1.size() << '\n';
    std::string str2 = "Jumped\n Over\tA\vLazy \t  Fox\r\n";
    str2.erase(std::remove_if(str2.begin(), 
                              str2.end(),
                              [](unsigned char x) { return std::isspace(x); }),
               str2.end());
    std::cout << "5) " << std::quoted(str2) << '\n';
    std::vector<std::complex<double>> nums{{2, 2}, {1, 3}, {4, 8}};
    #ifdef __cpp_lib_algorithm_default_value_type
        nums.erase(std::remove(nums.begin(), nums.end(), {1, 3}), nums.end());
    #else
        nums.erase(std::remove(nums.begin(), nums.end(), std::complex<double>{1, 3}),
                   nums.end());
    #endif
    assert((nums == std::vector<std::complex<double>>{{2, 2}, {4, 8}}));
}

출력:

1) "Quick  Red  Dog"
2) "QuickRedDog Dog"
3) "QuickRedDog", size: 15
4) "QuickRedDog", size: 11
5) "JumpedOverALazyFox"

결함 보고서

다음의 동작 변경 결함 보고서들은 이전에 발표된 C++ 표준에 소급 적용되었습니다.

DR 적용 대상 게시된 동작 올바른 동작
LWG 283 C++98 T EqualityComparable 요구사항을 만족해야 했으나,
ForwardIt 의 값 타입이 항상 T 는 아님
ForwardIt 의 값 타입이
CopyAssignable 요구사항을 만족하도록 변경

참고 항목

특정 조건을 만족하는 요소들을 생략하고 요소 범위를 복사합니다
(function template)
범위 내에서 연속된 중복 요소들을 제거합니다
(function template)
특정 조건을 만족하는 요소들을 제거합니다
(algorithm function object)