Difference between revisions of "Template:cpp/container/erase2"
From cppreference.com
m (deque too) |
m (`= T` for inplace_vector: P2248R14, it also already present in N4988 (C++26 draft); +demo for `U = T`.) |
||
(14 intermediate revisions by 3 users not shown) | |||
Line 1: | Line 1: | ||
− | {{cpp/title|erase|erase_if {{ | + | {{#vardefine:cont|{{{1|inplace_vector}}}}}<!-- |
− | {{#switch:{{ | + | -->{{cpp/title|erase|erase_if{{small|(std::{{#var:cont}})}}}} |
+ | {{#switch:{{#var:cont}} | ||
|basic_string={{cpp/string/basic_string/navbar}} | |basic_string={{cpp/string/basic_string/navbar}} | ||
− | |#default={{cpp/container/{{ | + | |#default={{cpp/container/{{#var:cont}}/navbar}} |
}} | }} | ||
− | {{cpp/container/ | + | {{cpp/container/get types|{{#var:cont}}}} |
{{dcl begin}} | {{dcl begin}} | ||
− | {{dcl header|{{cpp/container/ | + | {{dcl header|{{cpp/container/get header|{{#var:cont}}}}}} |
− | {{dcl|since=c++ | + | {{#switch:{{#var:cont}} |
+ | |inplace_vector= | ||
+ | {{dcl|num=1|since=c++26|1= | ||
+ | template< class T, std::size_t N, class U = T > | ||
+ | constexpr typename std::inplace_vector<T, N>::size_type | ||
+ | erase( std::inplace_vector<T, N>& c, const U& value ); | ||
+ | }} | ||
+ | {{dcl|num=2|since=c++26| | ||
+ | template< class T, std::size_t N, class Pred > | ||
+ | constexpr typename std::inplace_vector<T, N>::size_type | ||
+ | erase_if( std::inplace_vector<T, N>& c, Pred pred ); | ||
+ | }} | ||
+ | | | ||
+ | {{dcl rev multi|num=1|anchor=1 | ||
+ | |since1=c++20|dcl1= | ||
template< {{#var:types}}, class U > | template< {{#var:types}}, class U > | ||
− | {{#switch:{{ | + | {{#switch:{{#var:cont}} |
− | |vector|basic_string=constexpr | + | |vector|basic_string=constexpr std::{{#var:cont}} |
− | |#default= | + | |#default= std::{{#var:cont}}}}<{{#var:types_short}}>::size_type |
− | erase( std::{{ | + | erase( std::{{#var:cont}}<{{#var:types_short}}>& c, const U& value ); |
+ | |since2=c++26|dcl2= | ||
+ | template< {{#var:types}}, class U = {{#var:type_def}} > | ||
+ | {{#switch:{{#var:cont}} | ||
+ | |vector|basic_string=constexpr std::{{#var:cont}} | ||
+ | |#default= std::{{#var:cont}}}}<{{#var:types_short}}>::size_type | ||
+ | erase( std::{{#var:cont}}<{{#var:types_short}}>& c, const U& value ); | ||
}} | }} | ||
{{dcl|since=c++20|num=2|1= | {{dcl|since=c++20|num=2|1= | ||
template< {{#var:types}}, class Pred > | template< {{#var:types}}, class Pred > | ||
− | {{#switch:{{ | + | {{#switch:{{#var:cont}} |
− | |vector|basic_string=constexpr | + | |vector|basic_string=constexpr std::{{#var:cont}} |
− | |#default= | + | |#default= std::{{#var:cont}}}}<{{#var:types_short}}>::size_type |
− | erase_if( std::{{ | + | erase_if( std::{{#var:cont}}<{{#var:types_short}}>& c, Pred pred ); |
+ | }} | ||
}} | }} | ||
{{dcl end}} | {{dcl end}} | ||
− | @1@ Erases all elements that compare equal to {{c|value}} from the container. {{#switch:{{ | + | @1@ Erases all elements that compare equal to {{c|value}} from the container. {{#switch:{{#var:cont}} |
− | + | ||
|basic_string | |basic_string | ||
+ | |vector | ||
+ | |inplace_vector | ||
|deque= | |deque= | ||
Equivalent to | Equivalent to | ||
{{source|1= | {{source|1= | ||
auto it = std::remove(c.begin(), c.end(), value); | auto it = std::remove(c.begin(), c.end(), value); | ||
− | auto r = {{#switch:{{ | + | auto r = {{#switch:{{#var:cont}}|basic_string|deque|vector=c.end() - it|std::distance(it, c.end())}}; |
c.erase(it, c.end()); | c.erase(it, c.end()); | ||
return r; | return r; | ||
Line 36: | Line 59: | ||
|list | |list | ||
|forward_list= | |forward_list= | ||
− | Equivalent to {{c|1=return c.remove_if([&](auto& elem) { return elem == value; });}} | + | Equivalent to {{c|1=return c.remove_if([&](auto& elem) { return elem == value; });}}. |
}} | }} | ||
− | @2@ Erases all elements that satisfy the predicate {{c|pred}} from the container. {{#switch:{{ | + | @2@ Erases all elements that satisfy the predicate {{c|pred}} from the container. {{#switch:{{#var:cont}} |
|vector | |vector | ||
+ | |inplace_vector | ||
|basic_string | |basic_string | ||
|deque= | |deque= | ||
Line 45: | Line 69: | ||
{{source|1= | {{source|1= | ||
auto it = std::remove_if(c.begin(), c.end(), pred); | auto it = std::remove_if(c.begin(), c.end(), pred); | ||
− | auto r = {{#switch:{{ | + | auto r = {{#switch:{{#var:cont}}|basic_string|deque|vector=c.end() - it|std::distance(it, c.end())}}; |
c.erase(it, c.end()); | c.erase(it, c.end()); | ||
return r; | return r; | ||
Line 51: | Line 75: | ||
|list | |list | ||
|forward_list= | |forward_list= | ||
− | Equivalent to {{c|1=return c.remove_if(pred);}} | + | Equivalent to {{c|1=return c.remove_if(pred);}}. |
}} | }} | ||
Line 58: | Line 82: | ||
{{par|c|container from which to erase}} | {{par|c|container from which to erase}} | ||
{{par|value|value to be removed}} | {{par|value|value to be removed}} | ||
− | {{par pred1|pred|if the element should be erased|t1={{#switch:{{ | + | {{par pred1|pred|if the element should be erased|t1={{#switch:{{#var:cont}}|basic_string=CharT|#default=T}}}} |
{{par end}} | {{par end}} | ||
Line 66: | Line 90: | ||
===Complexity=== | ===Complexity=== | ||
Linear. | Linear. | ||
− | {{#switch:{{ | + | <!----> |
+ | {{#switch:{{#var:cont}}|inplace_vector=<!--nothing--> | ||
+ | | | ||
+ | ===Notes=== | ||
+ | {{#switch:{{#var:cont}} | ||
|list | |list | ||
|forward_list= | |forward_list= | ||
− | + | Unlike {{lc|std::{{#var:cont}}::remove}}, {{tt|erase}} accepts heterogeneous types and does not force a conversion to the container's value type before invoking the {{c|1===}} operator. | |
− | Unlike {{lc|std::{{ | + | }} |
+ | {{feature test macro|__cpp_lib_algorithm_default_value_type|value=202403|std=C++26|[[cpp/language/list_initialization|List-initialization]] for algorithm {{vl|1}}}} | ||
}} | }} | ||
+ | <!----> | ||
===Example=== | ===Example=== | ||
− | {{#switch:{{ | + | {{#switch:{{#var:cont}} |
|basic_string= | |basic_string= | ||
{{example | {{example | ||
Line 96: | Line 126: | ||
std::cout << "After erase all 'a', 'r', and 't': " << std::quoted(word) << '\n'; | std::cout << "After erase all 'a', 'r', and 't': " << std::quoted(word) << '\n'; | ||
std::cout << "Erased symbols count: " << erased << '\n'; | std::cout << "Erased symbols count: " << erased << '\n'; | ||
+ | |||
+ | #if __cpp_lib_algorithm_default_value_type | ||
+ | std::erase(word, {'g'}); | ||
+ | std::cout << "After erase {'g'}: " << std::quoted(word) << '\n'; | ||
+ | #endif | ||
} | } | ||
+ | |p=true | ||
|output= | |output= | ||
Initially, word = "startling" | Initially, word = "startling" | ||
Line 102: | Line 138: | ||
After erase all 'a', 'r', and 't': "sing" | After erase all 'a', 'r', and 't': "sing" | ||
Erased symbols count: 4 | Erased symbols count: 4 | ||
+ | After erase {'g'}: "sin" | ||
+ | }} | ||
+ | |inplace_vector= | ||
+ | {{example | ||
+ | |code= | ||
+ | #include <cassert> | ||
+ | #include <complex> | ||
+ | #include <inplace_vector> | ||
+ | #include <numeric> | ||
+ | #include <print> | ||
+ | |||
+ | int main() | ||
+ | { | ||
+ | std::inplace_vector<int, 10> v(10, 0); | ||
+ | std::ranges::iota(v, 0); | ||
+ | std::println("Initially, v = {}", v); | ||
+ | |||
+ | auto erased = std::erase(v, 3); | ||
+ | std::println("After erase(v, 3), v = {}", v); | ||
+ | assert(erased == 1); | ||
+ | |||
+ | erased = std::erase_if(v, [](int x) { return x % 2 == 0; }); | ||
+ | std::println("After erasing all even numbers, v = {}", v); | ||
+ | std::println("Erased even numbers: {}", erased); | ||
+ | |||
+ | std::inplace_vector<std::complex<double>> nums{<!---->{2, 2}, {4, 2}, {4, 8}, {4, 2}<!---->}; | ||
+ | std::erase(nums, {4, 2}); // since U = T, the value type can be ommited | ||
+ | std::println("After erase {4, 2}, nums = {}", nums); | ||
+ | } | ||
+ | |output= | ||
+ | Initially, v = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] | ||
+ | After erase(v, 3), v = [0, 1, 2, 4, 5, 6, 7, 8, 9] | ||
+ | After erasing all even numbers, v = [1, 5, 7, 9] | ||
+ | Erased even numbers: 5 | ||
+ | After erase {4, 2}, nums = [(2,2), (4,8)] | ||
}} | }} | ||
| | | | ||
{{example | {{example | ||
|code= | |code= | ||
+ | #include <complex> | ||
#include <iostream> | #include <iostream> | ||
#include <numeric> | #include <numeric> | ||
#include <string_view> | #include <string_view> | ||
− | #include <{{ | + | #include <{{#var:cont}}> |
− | void | + | void println(std::string_view comment, const auto& c) |
{ | { | ||
− | std::cout << comment << | + | std::cout << comment << '['; |
− | for ( | + | bool first{true}; |
− | std::cout << | + | for (const auto& x : c) |
− | std::cout << " | + | std::cout << (first ? first = false, "" : ", ") << x; |
+ | std::cout << "]\n"; | ||
} | } | ||
int main() | int main() | ||
{ | { | ||
− | std::{{ | + | std::{{#var:cont}}<char> cnt(10); |
std::iota(cnt.begin(), cnt.end(), '0'); | std::iota(cnt.begin(), cnt.end(), '0'); | ||
− | + | println("Initially, cnt = ", cnt); | |
std::erase(cnt, '3'); | std::erase(cnt, '3'); | ||
− | + | println("After erase '3', cnt = ", cnt); | |
auto erased = std::erase_if(cnt, [](char x) { return (x - '0') % 2 == 0; }); | auto erased = std::erase_if(cnt, [](char x) { return (x - '0') % 2 == 0; }); | ||
− | + | println("After erase all even numbers, cnt = ", cnt); | |
std::cout << "Erased even numbers: " << erased << '\n'; | std::cout << "Erased even numbers: " << erased << '\n'; | ||
+ | |||
+ | std::{{#var:cont}}<std::complex<double>> nums{<!---->{2, 2}, {4, 2}, {4, 8}, {4, 2}<!---->}; | ||
+ | #ifdef __cpp_lib_algorithm_default_value_type | ||
+ | std::erase(nums, {4, 2}); | ||
+ | #else | ||
+ | std::erase(nums, std::complex<double>{4, 2}); | ||
+ | #endif | ||
+ | println("After erase {4, 2}, nums = ", nums); | ||
} | } | ||
|output= | |output= | ||
− | Initially, cnt = | + | Initially, cnt = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] |
− | After erase '3', cnt = | + | After erase '3', cnt = [0, 1, 2, 4, 5, 6, 7, 8, 9] |
− | After erase all even numbers, cnt = | + | After erase all even numbers, cnt = [1, 5, 7, 9] |
Erased even numbers: 5 | Erased even numbers: 5 | ||
+ | After erase {4, 2}, nums = [(2,2), (4,8)] | ||
}} | }} | ||
}} | }} | ||
Line 143: | Line 225: | ||
{{dsc begin}} | {{dsc begin}} | ||
{{dsc inc|cpp/algorithm/dsc remove}} | {{dsc inc|cpp/algorithm/dsc remove}} | ||
− | {{#switch:{{ | + | {{dsc inc|cpp/algorithm/ranges/dsc remove}} |
+ | {{#switch:{{#var:cont}} | ||
|list | |list | ||
|forward_list= | |forward_list= | ||
− | {{dsc inc|cpp/container/dsc remove|{{ | + | {{dsc inc|cpp/container/dsc remove|{{#var:cont}}}} |
}} | }} | ||
{{dsc end}} | {{dsc end}} |
Latest revision as of 15:59, 22 September 2024
Defined in header <inplace_vector>
|
||
template< class T, std::size_t N, class U = T > constexpr typename std::inplace_vector<T, N>::size_type |
(1) | (since C++26) |
template< class T, std::size_t N, class Pred > constexpr typename std::inplace_vector<T, N>::size_type |
(2) | (since C++26) |
1) Erases all elements that compare equal to value from the container. Equivalent to
auto it = std::remove(c.begin(), c.end(), value); auto r = std::distance(it, c.end()); c.erase(it, c.end()); return r;
2) Erases all elements that satisfy the predicate pred from the container. Equivalent to
auto it = std::remove_if(c.begin(), c.end(), pred); auto r = std::distance(it, c.end()); c.erase(it, c.end()); return r;
Contents |
[edit] Parameters
c | - | container from which to erase |
value | - | value to be removed |
pred | - | unary predicate which returns true if the element should be erased. The expression pred(v) must be convertible to bool for every argument |
[edit] Return value
The number of erased elements.
[edit] Complexity
Linear.
[edit] Example
Run this code
#include <cassert> #include <complex> #include <inplace_vector> #include <numeric> #include <print> int main() { std::inplace_vector<int, 10> v(10, 0); std::ranges::iota(v, 0); std::println("Initially, v = {}", v); auto erased = std::erase(v, 3); std::println("After erase(v, 3), v = {}", v); assert(erased == 1); erased = std::erase_if(v, [](int x) { return x % 2 == 0; }); std::println("After erasing all even numbers, v = {}", v); std::println("Erased even numbers: {}", erased); std::inplace_vector<std::complex<double>> nums{{2, 2}, {4, 2}, {4, 8}, {4, 2}}; std::erase(nums, {4, 2}); // since U = T, the value type can be ommited std::println("After erase {4, 2}, nums = {}", nums); }
Output:
Initially, v = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] After erase(v, 3), v = [0, 1, 2, 4, 5, 6, 7, 8, 9] After erasing all even numbers, v = [1, 5, 7, 9] Erased even numbers: 5 After erase {4, 2}, nums = [(2,2), (4,8)]
[edit] See also
removes elements satisfying specific criteria (function template) | |
(C++20)(C++20) |
removes elements satisfying specific criteria (niebloid) |