Difference between revisions of "Template:cpp/container/erase2"
From cppreference.com
m (generalize) |
m (`= T` for inplace_vector: P2248R14, it also already present in N4988 (C++26 draft); +demo for `U = T`.) |
||
(37 intermediate revisions by 7 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:{{#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 ); | ||
+ | |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:{{#var:cont}} | |
+ | |vector|basic_string=constexpr std::{{#var:cont}} | ||
+ | |#default= std::{{#var:cont}}}}<{{#var:types_short}}>::size_type | ||
+ | erase_if( std::{{#var:cont}}<{{#var:types_short}}>& c, Pred pred ); | ||
+ | }} | ||
}} | }} | ||
{{dcl end}} | {{dcl end}} | ||
− | @1@ Erases all elements that compare equal to {{ | + | @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= | ||
+ | auto it = std::remove(c.begin(), c.end(), value); | ||
+ | auto r = {{#switch:{{#var:cont}}|basic_string|deque|vector=c.end() - it|std::distance(it, c.end())}}; | ||
+ | c.erase(it, c.end()); | ||
+ | return r; | ||
+ | }} | ||
|list | |list | ||
|forward_list= | |forward_list= | ||
− | Equivalent to {{c|1=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 {{ | + | @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= | ||
− | Equivalent to {{ | + | Equivalent to |
+ | {{source|1= | ||
+ | auto it = std::remove_if(c.begin(), c.end(), pred); | ||
+ | auto r = {{#switch:{{#var:cont}}|basic_string|deque|vector=c.end() - it|std::distance(it, c.end())}}; | ||
+ | c.erase(it, c.end()); | ||
+ | return r; | ||
+ | }} | ||
|list | |list | ||
|forward_list= | |forward_list= | ||
− | Equivalent to {{c|1=c.remove_if(pred);}} | + | Equivalent to {{c|1=return c.remove_if(pred);}}. |
}} | }} | ||
===Parameters=== | ===Parameters=== | ||
{{par begin}} | {{par begin}} | ||
− | {{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}} |
+ | |||
+ | ===Return value=== | ||
+ | The number of erased elements. | ||
===Complexity=== | ===Complexity=== | ||
Linear. | Linear. | ||
− | + | <!----> | |
+ | {{#switch:{{#var:cont}}|inplace_vector=<!--nothing--> | ||
+ | | | ||
+ | ===Notes=== | ||
+ | {{#switch:{{#var:cont}} | ||
+ | |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. | ||
+ | }} | ||
+ | {{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:{{#var:cont}} | ||
+ | |basic_string= | ||
{{example | {{example | ||
− | + | |code= | |
+ | #include <iomanip> | ||
#include <iostream> | #include <iostream> | ||
+ | #include <string> | ||
+ | |||
+ | int main() | ||
+ | { | ||
+ | std::string word{"startling"}; | ||
+ | std::cout << "Initially, word = " << std::quoted(word) << '\n'; | ||
+ | |||
+ | std::erase(word, 'l'); | ||
+ | std::cout << "After erase 'l': " << std::quoted(word) << '\n'; | ||
+ | |||
+ | auto erased = std::erase_if(word, [](char x) | ||
+ | { | ||
+ | return x == 'a' or x == 'r' or x == 't'; | ||
+ | }); | ||
+ | |||
+ | std::cout << "After erase all 'a', 'r', and 't': " << std::quoted(word) << '\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= | ||
+ | Initially, word = "startling" | ||
+ | After erase 'l', word = "starting" | ||
+ | After erase all 'a', 'r', and 't': "sing" | ||
+ | Erased symbols count: 4 | ||
+ | After erase {'g'}: "sin" | ||
+ | }} | ||
+ | |inplace_vector= | ||
+ | {{example | ||
+ | |code= | ||
+ | #include <cassert> | ||
+ | #include <complex> | ||
+ | #include <inplace_vector> | ||
#include <numeric> | #include <numeric> | ||
− | #include < | + | #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 | ||
+ | |code= | ||
+ | #include <complex> | ||
+ | #include <iostream> | ||
+ | #include <numeric> | ||
+ | #include <string_view> | ||
+ | #include <{{#var:cont}}> | ||
+ | |||
+ | void println(std::string_view comment, const auto& c) | ||
{ | { | ||
− | for (auto x : | + | std::cout << comment << '['; |
− | std::cout << | + | bool first{true}; |
− | + | 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:: | + | std::erase(cnt, '3'); |
− | + | println("After erase '3', cnt = ", cnt); | |
− | std:: | + | auto erased = std::erase_if(cnt, [](char x) { return (x - '0') % 2 == 0; }); |
− | std::cout << " | + | println("After erase all even numbers, cnt = ", cnt); |
− | + | std::cout << "Erased even numbers: " << erased << '\n'; | |
− | std:: | + | std::{{#var:cont}}<std::complex<double>> nums{<!---->{2, 2}, {4, 2}, {4, 8}, {4, 2}<!---->}; |
− | std:: | + | #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= | |
− | + | Initially, cnt = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] | |
− | 0 1 2 3 4 5 6 7 8 9 | + | After erase '3', cnt = [0, 1, 2, 4, 5, 6, 7, 8, 9] |
− | + | After erase all even numbers, cnt = [1, 5, 7, 9] | |
− | 0 1 2 | + | Erased even numbers: 5 |
− | + | After erase {4, 2}, nums = [(2,2), (4,8)] | |
− | 1 | + | |
}} | }} | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
}} | }} | ||
===See also=== | ===See also=== | ||
− | |||
{{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) |