Is there a standard algorithm that I can use to subset a vector of structs by a vector of pointers to these structs?
E.g.
typedef struct {
int a;
char b;
} some_struct_t;
int main()
{
std::vector<some_struct_t> v = { {10, '1'}, { 5, '2'} };
std::vector<some_struct_t*> v2;
std::some_subset_command<some_struct_t, some_struct_t*>(begin(v), end(v), std::back_inserter(v2), [](const somestruct&) { if (somestruct.a == 5) { return &somestruct; }});
}
some_subset_command()
should construct the new vector using the back_inserter
and the output from the lambda predicate.
How can I do this in the most declarative way?
CodePudding user response:
If you don't mind changing your std::vector<some_struct_t*> v2
to a std::vector<std::reference_wrapper<some_struct_t>> v2
(include <functional>
), you could use std::copy_if
:
#include <vector>
#include <algorithm>
#include <functional>
typedef struct {
int a;
char b;
} some_struct_t;
int main()
{
std::vector<some_struct_t> v = { {10, '1'}, { 5, '2'} };
std::vector<std::reference_wrapper<some_struct_t>> v2;
std::copy_if(begin(v), end(v), std::back_inserter(v2), [](const auto &s) {
return s.a == 5;
});
}
More information for std::reference_wrapper
at cppreference.
CodePudding user response:
If your compiler supports C 20, then you can use range adaptors:
#include <ranges>
#include <vector>
typedef struct {
int a;
char b;
} some_struct_t;
int main()
{
std::vector<some_struct_t> v = { {10, '1'}, { 5, '2'} };
auto r = v | std::views::filter([](auto& somestruct) { return somestruct.a == 5; })
| std::views::transform([](auto& somestruct) { return &somestruct; });
std::vector<some_struct_t*> v2(r.begin(), r.end());
}