转换std :: vector <boost :: optional <double>&gt;到std :: vector <double>

时间:2018-04-30 08:21:33

标签: c++

我有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的解决方案,即使我还没有使用该标准。

2 个答案:

答案 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走上自己的路线。

我认为编写一个可以解决此问题的转换迭代器是可能的,但你必须从头开始。