Constrained algorithms and algorithms on ranges(C++20) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Constrained algorithms, e.g.ranges::copy,ranges::sort, ... | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Execution policies(C++17) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Numeric operations | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Operations on uninitialized memory | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Defined in header <algorithm> | ||
template<class ForwardIt> ForwardIt unique( ForwardIt first, ForwardIt last); | (1) | (constexpr since C++20) |
template<class ExecutionPolicy,class ForwardIt> ForwardIt unique( ExecutionPolicy&& policy, | (2) | (since C++17) |
template<class ForwardIt,class BinaryPred> ForwardIt unique( ForwardIt first, ForwardIt last, BinaryPred p); | (3) | (constexpr since C++20) |
template<class ExecutionPolicy, class ForwardIt,class BinaryPred> | (4) | (since C++17) |
Removes all except the first element from every consecutive group of equivalent elements from the range[
first,
last)
and returns a past-the-end iterator for the new end of the range.
std::is_execution_policy_v<std::decay_t<ExecutionPolicy>> istrue. | (until C++20) |
std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>> istrue. | (since C++20) |
Contents |
Removing is done by shifting the elements in the range in such a way that the elements that are not to be removed appear in the beginning of the range.
[
first,
last)
is not shortened by the removing operation. Givenresult as the returned iterator:[
result,
last)
are stilldereferenceable.
| (since C++11) |
first, last | - | the pair of iterators defining therange of elements to process |
policy | - | theexecution policy to use |
p | - | binary predicate which returns true if the elements should be treated as equal. The signature of the predicate function should be equivalent to the following: bool pred(const Type1&a,const Type2&b); While the signature does not need to haveconst&, the function must not modify the objects passed to it and must be able to accept all values of type (possibly const) |
Type requirements | ||
-ForwardIt must meet the requirements ofLegacyForwardIterator. | ||
-The type of dereferencedForwardIt must meet the requirements ofMoveAssignable. |
AForwardIt
to the new end of the range.
Given\(\scriptsize N\)N asstd::distance(first, last):
The overloads with a template parameter namedExecutionPolicy
report errors as follows:
ExecutionPolicy
is one of thestandard policies,std::terminate is called. For any otherExecutionPolicy
, the behavior is implementation-defined.See also the implementations inlibstdc++,libc++, andMSVC STL.
unique (1) |
---|
template<class ForwardIt>ForwardIt unique(ForwardIt first, ForwardIt last){if(first== last)return last; ForwardIt result= first;while(++first!= last)if(!(*result==*first)&&++result!= first)*result= std::move(*first); return++result;} |
unique (3) |
template<class ForwardIt,class BinaryPredicate>ForwardIt unique(ForwardIt first, ForwardIt last, BinaryPredicate p){if(first== last)return last; ForwardIt result= first;while(++first!= last)if(!p(*result,*first)&&++result!= first)*result= std::move(*first); return++result;} |
A call tounique
is typically followed by a call to a container'serase
member function to actually remove elements from the container.
#include <algorithm>#include <iostream>#include <vector> int main(){// a vector containing several duplicate elementsstd::vector<int> v{1,2,1,1,3,3,3,4,5,4};auto print=[&](int id){std::cout<<"@"<< id<<": ";for(int i: v)std::cout<< i<<' ';std::cout<<'\n';}; print(1); // remove consecutive (adjacent) duplicatesauto last= std::unique(v.begin(), v.end());// v now holds {1 2 1 3 4 5 4 x x x}, where 'x' is indeterminate v.erase(last, v.end()); print(2); // sort followed by unique, to remove all duplicatesstd::sort(v.begin(), v.end());// {1 1 2 3 4 4 5} print(3); last= std::unique(v.begin(), v.end());// v now holds {1 2 3 4 5 x x}, where 'x' is indeterminate v.erase(last, v.end()); print(4);}
Output:
@1: 1 2 1 1 3 3 3 4 5 4@2: 1 2 1 3 4 5 4@3: 1 1 2 3 4 4 5@4: 1 2 3 4 5
The following behavior-changing defect reports were applied retroactively to previously published C++ standards.
DR | Applied to | Behavior as published | Correct behavior |
---|---|---|---|
LWG 202 | C++98 | the behavior was unclear if the elements are compared using a non-equivalence relation | the behavior is undefined in this case |
finds the first two adjacent items that are equal (or satisfy a given predicate) (function template)[edit] | |
creates a copy of some range of elements that contains no consecutive duplicates (function template)[edit] | |
removes elements satisfying specific criteria (function template)[edit] | |
removes consecutive duplicate elements (public member function of std::list<T,Allocator> )[edit] | |
removes consecutive duplicate elements (public member function of std::forward_list<T,Allocator> )[edit] | |
(C++20) | removes consecutive duplicate elements in a range (algorithm function object)[edit] |