【问题标题】:C++11 How to use lambda and higher order functions to transform a vector to a vector of different typeC++11 如何使用 lambda 和高阶函数将向量转换为不同类型的向量
【发布时间】:2015-06-15 11:11:45
【问题描述】:

有没有办法在 C++11 中使用高阶函数返回不同类型的向量?我有一个 std::vector<std::string> 并想将其转换为 std::vector<Foo> 这是我自己设备的枚举。

假设我有一个方法Foo toFoo(std::string)。我试过了:

std::vector<Foo> m_Foos = std::for_each(m_Foo_strings.begin(),
        m_Foo_strings.end(), 
        [this](std::string &s){ toFoo(s); } );

也试过了:

std::vector<Foo> m_Foos = std::transform(m_Foo_strings.begin(),
        m_Foo_strings.end(),
        m_Foo_strings.begin(), 
        [this](std::string &s){ toFoo(s); } );

但两者都无法编译。它抱怨没有从 std::string 到 Foo 定义 operator=。

必须有一种通用的方法来做我在这里尝试的事情,我错过了什么?

【问题讨论】:

标签: c++ c++11 vector lambda stl


【解决方案1】:

std::transform 不返回 vector,它应用指定的转换并将结果存储在您传递给它的目标范围内

std::transform(m_Foo_strings.begin(),
               m_Foo_strings.end(),
               std::back_inserter(m_Foos),
               [this](std::string &s){ return toFoo(s); } );

back_inserter 构造一个back_insert_iterator,当transform 将调用结果分配给lambda 时,它将调用vector::push_back 将元素添加到m_Foos

【讨论】:

    【解决方案2】:
    std::vector<Foo> m_Foos;
    std::for_each(m_Foo_strings.begin(),
                  m_Foo_strings.end(), 
                  [this, &m_Foos](std::string &s){ m_Foos.push_back(toFoo(s)); } );
    

    【讨论】:

    • 这看起来很有希望,是否保证 for_each 与初始向量的遍历顺序相同?那么 m_Foo_strings 和 m_Foos 的顺序会是一样的吗?
    • 是的。请参阅documentation of std::for_each。 "将给定的函数对象 f 应用于 [first, last) 范围内的每个迭代器的解引用结果,按顺序。"
    【解决方案3】:

    我会使用基于范围的 for 循环。如果您从 begin 迭代到 end,则此方法有效,但如果您只想处理子集,则需要使用 for_eachtransform

    std::vector<Foo> m_Foos;
    for (const auto& s : m_Foo_strings) {
        m_Foos.push_back(toFoo(s));
    }
    

    【讨论】:

      猜你喜欢
      • 2017-01-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-21
      • 2017-03-26
      • 1970-01-01
      相关资源
      最近更新 更多