将 std::vector<boost::optional<double>> 转换为 std::vector<double>

Convert a std::vector<boost::optional<double>> to a std::vector<double>

本文关键字:gt lt vector std double 转换 boost optional      更新时间:2023-10-16

我有一个std::vector<boost::optional<double>>foo说。在这个特定实例中,我需要std::vector<double>,其中其他矢量中的任何"可选"元素映射到新矢量中的 0。

我是否缺少单行解决方案?

另一种选择是不尽如人意

std::vector<double> out(foo.size());
for (auto& it : foo){
out.push_back(it ? *it : 0.0);
}

我欢迎基于std::optional的解决方案,即使我还没有使用该标准。

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定义。

下面是使用所需值构造输出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 进入自己的行。

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