首页 > 解决方案 > 使用 std::transform 构造一个 std::vector。返回未命名结果的可能性?

问题描述

让我们

class InputClass; 
class OutputClass; 

OutputClass const In2Out(InputClass const &in)
{
    //conversion implemented
}

最后

std::vector<OutputClass> Convert(std::vector<InputClass> const &input)
{
    std::vector<OutputClass> res;
    res.reserve(input.size());
    //either 
    for (auto const &in : input)
        res.emplace_back(In2Out(in));
    return res;
    //or something like
    std::transform(input.begin(), input.end(), std::back_inserter(res), [](InputClass const &in){return In2Out(in);});
    return res;
}  

现在我的问题

我可以以某种方式重写 Convert 函数以避免需要命名新容器吗?IE。有没有办法直接使用类似于 std::transform 或 std::for_each 的东西来构造向量?

如(伪代码,这毫不奇怪甚至无法构建)

std::vector<OutputClass> Convert(std::vector<InputClass> const &input)
{
    return std::transform(input.begin(), input.end(), std::back_inserter(std::vector<OutputClass>()), [](InputClass const &in){return In2Out(in);});
}

搜索,但没有找到任何优雅的解决方案。谢谢!

标签: c++constructorstdvector

解决方案


从 C++ 20 开始,您可以使用 newstd::ranges::transform_view来完成您想要的。它将为它正在适应的容器中的每个元素调用您的转换函数,您可以使用该视图来调用std::vector的迭代器范围构造函数,该构造函数将为整个向量分配一次内存,然后填充元素。它仍然需要您在函数中创建一个变量,但它变得更加精简。那会给你类似的东西

std::vector<OutputClass> Convert(std::vector<InputClass> const &input)
{
    auto range = std::ranges::transform_view(input, In2Out);
    return {range.begin(), range.end()};
}

请注意,这应该优化到您的函数生成的完全相同的代码。


推荐阅读