can you help explain me how to use std::transform
?
I need to create a function that returns a string and has a string as parameter
and use std::transform
to convert all the uppercase char to lower and vice versa lowercase char to uppercase
example:
input = "aBc"
output = "AbC"
and i want to do it with a lambda, not using other mehtod like toupper, etc.
this is what i have so far which doesnt work, it compiles and runs but it returns nothing/ empty string;
std::string func(std::string inputString){
std::string result;
std::transform(inputString.begin(), inputString.end(), result.begin(), [](char& c){
if (c < 97) return c 32;
if (c >= 97) return c - 32;
});
return result;
}
CodePudding user response:
You haven't allocated any space in result
, so you are observing a pretty gentle case of undefined behavior (gentle because it's observably not working, rather than happening to work by pure luck).
So you either allocate such memory before calling std::transform
, e.g. via
result.resize(inputString.size());
or you can use a back_inserter
for result
, instead of its begin iterator result.begin()
, which will take care of the allocation; the page on std::transform
has such an example. In this latter case, is still probably a good idea to reserve some space via
result.reserve/* not resize! */(inputString.size());
CodePudding user response:
The cause of the problem:
You haven't allocated memory for result
.
You can cope with it in one of the following ways:
- Allocate memory explicitly using
std::string::resize
before callingstd::transform
:
result.resize(inputString.length());
- Use
std::back_inserter
instead ofresult.begin()
when callingstd::transform
:
std::transform(inputString.begin(), inputString.end(), std::back_inserter(result), [](char& c) {
Note: your lambda's body can be simplified to:
if (c < 97) return c 32;
return c - 32;
It will also fix a compiler warning (MSVC at least complained that the lambda is not always returning a value).