I'd like to know if it is possible to use std::back_inserter
to create a vector of only a single element from a more complex struct. For example, in the following code:
struct Person {
std::string first_name;
std::string last_name;
int id;
};
std::vector<Person> people;
// Populate 'people'...
// Extract last names into single vector
std::vector<std::string> last_names;
std::copy(begin(people), end(people), std::back_inserter(last_names)); // <... ?
The only solution I've found so far is to create a casting operator Person -> std::string
:
struct Person {
// ...
operator std::string() const { return last_name; }
};
But is not a good solution if I want to extract first_name
and last_name
into two vectors, not to mention how obscure becomes such implicit conversion.
Is there any way to indicate std::back_inserter
how to construct the element to insert? Any other way to create such vector? Obviously, I'm not referring to the raw way:
std::vector<std::string> last_names;
last_names.reserve(people.size());
for (const auto& person : people) {
last_names.push_back(person.last_name);
}
but to some <algorithm>
-like one ;)
I'd prefer a C++-only answer, but I'm open to Boost solutions if needed.
You should use std::transform
instead, with an unary operation function object to perform the transformation on every element. eg
std::transform(std::begin(people),
std::end(people),
std::back_inserter(last_names),
[](const Person& person) { return person.last_name; }
);
Just to add alternatives you could also use std/boost::bind
// Extract first names into single vector
std::vector<std::string> last_names;
last_names.reserve(people.size());
std::transform(people.begin(), people.end(), std::back_inserter(last_names),
std::bind(&Person::last_name, std::placeholders::_1));
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.