std :: back_inserter的std :: set吗?


94

我想这是一个简单的问题。我需要做这样的事情:

std::set<int> s1, s2;
s1 = getAnExcitingSet();
std::transform(s1.begin(), s1.end(), std::back_inserter(s2), ExcitingUnaryFunctor());

当然,std::back_inserter因为没有,所以不起作用push_backstd::inserter还需要一个迭代器?我没有用过,std::inserter所以不确定该怎么做。

有人有主意吗?


当然,我的另一个选择是对使用向量s2,然后稍后对其进行排序。也许更好?

Answers:


139

set不需要,push_back因为元素的位置由集合的比较器确定。使用std::inserter并通过它.begin()

std::set<int> s1, s2;
s1 = getAnExcitingSet();
transform(s1.begin(), s1.end(), 
          std::inserter(s2, s2.begin()), ExcitingUnaryFunctor());

然后,插入迭代器将调用s2.insert(s2.begin(), x)where,x即写入该迭代器时传递给该迭代器的值。该集合使用迭代器作为插入位置的提示。您也可以使用s2.end()


2
既然也inserter(vec, vec.end())适用于矢量,那么为什么有人首先使用back_inserter?
NHDaly 2014年

7
@NHDaly:因为back_inserter速度更快
marton78

@ marton78但是,难道不应该只是以很小的幅度提高速度吗?当不需要移动任何元素时,调用insert而不是调用push_back向量应该大致相同(O(1))。
Felix Dombek '18

3
@FelixDombek你是对的,不会慢很多。v.insert(x, v.end())将在开始处有一个额外的分支(由于它移动了n个元素,但此处n为零)。但是,使用inserter1)传达的意图与使用push_back2 )传达的意图不同,这使读者停下来并认为3)是过早的悲观。
marton78 '18

0

在2016年,有人提出了一个“单参数inserter迭代器”的建议。 https://isocpp.org/files/papers/p0471r0.html。我找不到提案是否通过。我认为这是有道理的。

现在,您可以通过以下行为定义maker函数:

template<class Container>
auto sinserter(Container& c){
    using std::end;
    return std::inserter(c, end(c));
}

用作:

std::transform(begin(my_vec), end(my_vec), sinserter(my_set), [](auto& e){return e.member;});

是否打算在所有标准容器上使用?在std :: forward_list上不起作用(编译器错误是在的实例化内,“ forward_list没有名为'insert'的成员” insert_iterator::operator=)。应该是?
唐·哈奇

@DonHatch,具有insert(和end)的任何东西。似乎最初forward_list没有任何insert操作insert_after。我认为,即使已更改,也无法在结束后插入。您不能使用a std::list吗?
alfC

当然,我个人不需要std :: forward_list。但是我对通用的“如何将一个容器复制到另一个容器”感兴趣。对于所有有意义的容器。我目前的兴趣是练习通用容器分配器,例如@HowardHinnant的short_alloc。
唐·哈奇

@DonHatch,问题是该问题有很多变体。(““如何将一个容器复制到另一个容器?”。)例如,您要保留原始值,是否要最小化分配等?对于最简单的情况,我认为最好的答案是使用构造函数两个迭代器容器(最容器可以采取)。 NewContaner new_container(old_other_container.begin(), old_other_container.end())
alfC

1
是的,std :: set不是SequentialContainer,这很好:-) existing_list = std::list(c.begin(), c.end(), existing_list.get_allocator()) 很好,我想这就是我的答案。干杯!
Don Hatch
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.