I have a std::vector<boost::optional<double>>
, foo
say. In this particular instance I need a std::vector<double>
where any "optional" element in the other vector maps to a 0 in the new one.
Am I missing a one-line solution for this?
The other choice is the unsatisfactory
std::vector<double> out(foo.size());
for (auto& it : foo){
out.push_back(it ? *it : 0.0);
}
I'd welcome a solution based on std::optional
, even though I don't use that standard yet.
std::transform
solution:
std::vector<double> out(foo.size());
std::transform(foo.begin(), foo.end(), out.begin(), [](const auto& opt){ return opt.value_or(0.0); });
Edit: Added the out
definition.
Here's a solution that constructs the output vector
with the desired values. Still can't be forced onto one line though.
auto valueOrZero = [](auto opt){ return opt?*opt:0.0; };
std::vector<double> out(boost::make_transform_iterator(std::begin(foo), valueOrZero), boost::make_transform_iterator(std::end(foo), valueOrZero));
Unfortunately, boost::transform_iterator
requires the unary transformation function to be specified for the end iterator, and you can't just repeat the lamdba definition because it also requires both iterators to have exactly the same type. This forces the lambda onto its own line.
I think it would be possible to write a transform iterator that works around this, but you'd have to do it from scratch.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With