idiomatic C++,用于从std :: map的最后n个元素创建std :: vector

Ale*_*son 4 c++ idioms vector map

从std :: map的最后n个元素创建std :: vector的C++惯用方法是什么?

我对保存向量中的顺序不感兴趣.

我可以复制元素,如下所示:

    std::map< double, MyType > m;
    size_t n = 3;
    std::vector< MyType > v;
    std::map< double, MyType >::iterator it = m.end();
    while ( n-- ) { // assuming m.size() >= n
        it--;
        v.push_back(it->second);
    }
Run Code Online (Sandbox Code Playgroud)

但是,有没有其他方式,更惯用,做到这一点?

jal*_*alf 5

std::copy如果你想复制类型不变,那将是合适的.但是,std::map<T,U>::iterator_type::value_type不是U(要复制的类型),但是std::pair<T,U>(换句话说,取消引用映射迭代器会产生一对键和值类型),因此原始副本将不起作用.

所以我们需要复制元素,沿途进行转换.这std::transform是为了什么.

为方便起见,我将假设您的编译器支持C++ 11 lambda表达式和auto关键字.如果没有,它可以相当简单地重写为仿函数.但我们正在寻找类似于此的东西:

std::transform(map_first, map_last, std::back_inserter(vec), [](std::pair<double,MyType> p) { return p.second; });
Run Code Online (Sandbox Code Playgroud)

现在我们只需要填写两个第一个参数:

auto map_first = std::next(map.end(), -n); 
auto map_last = map.end();
Run Code Online (Sandbox Code Playgroud)

这里唯一棘手的部分是地图迭代器是双向的,但不是随机访问,所以我们不能简单地说map.end() - n.该-运营商没有定义.相反,我们必须使用std::next(对于双向运算符,它需要线性而不是恒定的时间,但是没有办法解决这个问题).

(注意,我还没有尝试编译这段代码,因此可能需要进行一些调整)

  • 在回答被问到的问题时没有必要.是的,它在实际编写工作代码时是必不可少的,但我也很方便地省略了许多其他内容.OP询问如何从地图的最后N个元素创建一个向量(这意味着地图中的最后N个元素实际存在),这就是我试图回答的问题.无论如何,我只是按照我个人喜欢的方式去做,当我提出问题时,我到目前为止更喜欢坚持这一点的答案,并且不要尝试将其与我所做的六件事捆绑在一起. t*需要知道.:) YMMV (3认同)