我有std::vector<boost::optional<double>>
,foo
说。在这个特定的例子中,我需要一个std::vector<double>
,其中任何&#34;可选&#34;另一个向量中的元素映射到新元素中的0。
我是否错过了这方面的单行解决方案?
另一个选择是不满意的
std::vector<double> out(foo.size());
for (auto& it : foo){
out.push_back(it ? *it : 0.0);
}
我欢迎基于std::optional
的解决方案,即使我还没有使用该标准。
答案 0 :(得分:15)
std::transform
解决方案:
std::vector<double> out(foo.size());
std::transform(foo.begin(), foo.end(), out.begin(), [](const auto& opt){ return opt.value_or(0.0); });
修改:添加了out
定义。
答案 1 :(得分:4)
这是一个使用所需值构造输出vector
的解决方案。仍然不能强迫一条线。
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));
不幸的是,boost::transform_iterator
要求为结束迭代器指定一元变换函数,并且不能只重复lamdba定义,因为它还要求两个迭代器具有完全相同的类型。这会迫使lambda走上自己的路线。
我认为编写一个可以解决此问题的转换迭代器是可能的,但你必须从头开始。