I'm trying to transform a vector of foo instances to a string but I'm having fatal error on std::transform.
Say data
has the following value:
[0]
[name] = John
[size] = 3423
[1]
[name] = Joseph
[size] = 3413
Code:
struct foo {
foo(std::string n, size_t s)
: name(std::move(n)),
size(s)
{
}
std::string name;
size_t size;
};
std::string server = "1";
std::vector<std::string> output;
output.reserve(static_cast<unsigned_long>(std::distance(std::begin(data), std::end(data))));
std::transform(std::begin(data),
std::end(data),
std::begin(output),
[&, this](foo const& item){
std::ostringstream result;
data << server << ","
<< item.name << ","
<< item.size << ";";
return result.str();
});
While debugging it stops at the line
*__result = __unary_op(*_first)
of tranform
implementation in stl_algo.h
then goes to FatalConditionHandler of catch test framework. I'm new to both catch testing and std::transform. Can someone explain what might cause the problem and how to solve it? Thanks a lot!
You've reserved space in
output
, but you've left its size at zero.You then proceed to write through its
begin
iterator, just as if it had space to hold data.Then everything goes "boom".
Instead of writing through
std:begin(output)
, consider usingstd::back_inserter(output)
as the destination iterator.You also have one other problem: inside your lambda, you have:
This looks like a fairly obvious mistake--you undoubtedly intended:
Personally, I'd probably structure the code somewhat differently. I'd add something like:
...then the lambda in your transform becomes rather simpler:
It might, however, be worth considering doing this without the
stringstream
itermediaries at all. In this case, you really just need string concatenation, and they impose quite a bit of overhead to do that.Then the lambda body becomes:
Shorter, simpler, and almost certainly faster.