【问题标题】:Replacing std::transform, inserting into a std::vector替换std :: transform,插入std :: Vector
【发布时间】:2016-02-04 23:59:52
【问题描述】:

我希望以类似于 std::transform 的方式将值插入到 std::vector 中。 std::transform 需要一个预先确定大小的第三个参数,但在我的情况下,大小取决于 transformers() 并且不可预测。

...
// std::vector<int> new_args(); <-- not working
std::vector<int> new_args(args.size());
std::transform(args.begin(),args.end(),new_args.begin(),transformers());

是否有一种 std:transform-ish 方式将值插入到 std::vector 中?

【问题讨论】:

  • This 可能会有所帮助
  • 大小如何取决于transformers?你做某种过滤吗?如果是这样,你怎么知道是否有东西被过滤了?请澄清。
  • std::vector&lt;int&gt; new_args(); 声明一个函数(最麻烦的解析),它应该是std::vector&lt;int&gt; new_args;std::vector&lt;int&gt; new_args{};。 (然后std::back_inserter 解决您真正的问题)。
  • @Karoly 是的,这是一种过滤。例如,如果 args[1].size()==1,则不应向 new_args 添加任何内容。
  • @user1587451:添加完整解释,也许还有代码。另外,搜索transform_if(不是标准的一部分)。

标签: c++ c++11 stl stl-algorithm


【解决方案1】:

您可以使用std::back_inserter,它使用.push_back 向向量添加值:

std::vector<int> new_args;
std::transform(args.begin(),args.end(),std::back_inserter(new_args),transformers());

顺便说一句:std::vector&lt;int&gt; new_args(); 是一个函数声明。你可以用std::vector&lt;int&gt; new_args;创建一个空的std::vector

【讨论】:

    【解决方案2】:

    您不需要预先调整将要使用变换填充的向量的大小。使用std::back_inserter 它将充当向量的迭代器,但实际上会调用push_back() 将元素插入向量中。

    所以你的代码看起来像

    std::vector<int> new_args;
    new_args.reserve(args.size); // use this so you don't have grow the vector geometrically.
    std::transform(args.begin(),args.end(),std::back_inserter(new_args),transformers());
    

    【讨论】:

    • You do not need to pre size the vector that is going to be filled with transform 怎么会这样?如果我想 push_back 50000 个元素,我想保留它。
    • @Lorac back_inserter 通过调用 push_back 工作,因此它会在需要时调整向量的大小。如果你不想这样,那么你需要在默认构造向量后调用reserve
    【解决方案3】:

    感谢上帝,有 boost::range。

    由于输入和输出的大小和类型不同,std::copy_if 和 std::transform 没有帮助。

    #include <boost/range/adaptor/filtered.hpp>
    #include <boost/range/adaptor/transformed.hpp>
    #include <boost/range/algorithm_ext/push_back.hpp>
    #include <iostream>
    #include <vector>
    #include <string>
    #include <cmath>
    
    struct is_even
    {
        bool operator()(int x) const {return x%2==0;}
    };
    
    struct to_square_root
    {
        float operator()(int x) const {return std::sqrt(x);}
    };
    
    int main(int argc, const char* argv[])
    {
        std::vector<int> input={1,2,3,4,5,6,7,8,9};
        std::vector<float> output;
    
        boost::push_back (
            output
          , input
          | boost::adaptors::filtered(is_even())
          | boost::adaptors::transformed(to_square_root())
        );
    
        for(auto i: output) std::cout << i << "\n";
    }
    

    【讨论】:

      猜你喜欢
      • 2013-08-18
      • 1970-01-01
      • 2018-05-31
      • 2020-01-23
      • 2018-04-07
      • 2019-05-07
      • 1970-01-01
      • 2012-02-24
      • 2023-03-07
      相关资源
      最近更新 更多