I have the following small and easy code:
int main(int argc, char *argv[]) {
std::vector<std::string> in;
std::set<std::string> out;
in.push_back("Hi");
in.push_back("Dear");
in.push_back("Buddy");
for (const auto& item : in) {
*** std::transform(item.begin(),item.end(),item.begin(), ::tolower);
*** out.insert(item);
}
return 0;
}
I'd like to copy all items of in
into out
.
However, with an in-place lowercase conversion, preferrably without an extra temporary variable.
So this is the required content of out
at the end:
hi
dear
buddy
Please note, const auto& item
is fixed, meaning I can't remove the const
requirement (this is part of a bigger library, here is over-simplified for demo).
How should I do this? (If I remove the "const" modifier, it works, but if modifications are not allowed on item
, how can I still insert the item into the set, while also transforming it to lowercase?)
CodePudding user response:
You need a lambda function with transform, and you shouldn't have a const & to your strings or transform can't modify it.
#include <algorithm>
#include <set>
#include <string>
#include <vector>
int main()
{
std::vector<std::string> in;
std::set<std::string> out;
in.push_back("Hi");
in.push_back("Dear");
in.push_back("Buddy");
for (/*const*/ auto& item : in) // you can't have a const & if your going to modify it.
{
std::transform(item.begin(), item.end(), item.begin(), [](const char c)
{
return static_cast<char>(::tolower(c));
});
out.insert(item);
}
return 0;
}
CodePudding user response:
Note, you have to copy - since items in the original in
container can not be moved into out
container. The below code makes the copy of each element exactly once.
...
in.push_back("Hi");
in.push_back("Dear");
in.push_back("Buddy");
std::transform(in.begin(), in.end(), std::inserter(out, out.end()),
[] (std::string str) { boost::algorithm::to_lower(str); return str;}
);
return 0;