gpt4 book ai didi

c++ - std::为无序集(或映射)插入迭代器?

转载 作者:行者123 更新时间:2023-12-04 04:41:19 25 4
gpt4 key购买 nike

std::中是否有插入迭代器?对于无序集合?据我所知,std::inserter需要一个迭代器参数。这对于无序容器(至少对于 boost::unordered_set )是不安全的,因为它们可能会在 insert 期间重新分配操作并渲染通过的 .begin()迭代器无效。

所以目前我必须传递我自己的迭代器,它本质上是一个 boost::function_output_iterator使用一个简单地调用 unorderedSet.insert(param1) 的仿函数.

为什么会这样std::inserter甚至需要 hint迭代器参数呢?

最佳答案

没有。 hint的原因参数是std::inserter用于在插入上下文中需要位置的容器。如您所知,无序容器不是这种情况。
vector在一个容器的例子中,知道 position是插入的要求。来自 cppreference :

(1)
iterator insert( iterator pos, const T& value ); // (until C++11)
iterator insert( const_iterator pos, const T& value ); // (since C++11)

 (2)
iterator insert( const_iterator pos, T&& value ); // (since C++11)

(3)     
void insert( iterator pos, size_type count, const T& value ); // (until C++11)
iterator insert( const_iterator pos, size_type count, const T& value ); // (since C++11)

(4)     
template< class InputIt >
void insert( iterator pos, InputIt first, InputIt last); // (until C++11)
template< class InputIt >
iterator insert( const_iterator pos, InputIt first, InputIt last ); // (since C++11)

(5)
iterator insert( const_iterator pos, std::initializer_list<T> ilist ); // (since C++11)

Inserts elements at the specified location in the container.

  1-2) inserts value before pos
  3) inserts count copies of the value before pos
  4) inserts elements from range [first, last) before pos.
       This overload has the same effect as overload (3) if InputIt is an integral type. (until C++11)
       This overload only participates in overload resolution if InputIt qualifies as LegacyInputIterator, to avoid ambiguity with the overload (3). (since C++11) The behavior is undefined if first and last are iterators into *this.
  5) inserts elements from initializer list ilist before pos.



我知道这不是您要寻找的答案,但是推出自己的答案很容易,即使不是有点冗长:
template<typename Container>
class unordered_inserter {
public:
using iterator_category = std::output_iterator_tag;
using value_type = void;
using reference_type = void;
using difference_type = void;
using pointer = void;
using reference = void;
using container_type = Container;

unordered_inserter& operator++() {return *this;} //no-op
unordered_inserter& operator++(int) {return *this;} //no-op
unordered_inserter& operator*() {return *this;} //no-op
constexpr unordered_inserter& operator=(const typename Container::value_type& value) {
container->insert(value);
return *this;
}
constexpr unordered_inserter& operator=(typename Container::value_type&& value) {
container->insert(std::move(value));
return *this;
}
unordered_inserter(Container* container)
: container(container)
{}
protected:
Container* container;
};

这可能可以重构以支持其他类型的插入,但我认为现在就足够了。

这是我玩的一点:
int main() {
std::unordered_map<int, int> m;
std::istringstream iss("1 2 3 4 5 6");

std::transform(std::istream_iterator<int>(iss), std::istream_iterator<int>(), unordered_inserter(&m), [](int v) {
return decltype(m)::value_type{v, v*v};
});
std::transform(m.begin(), m.end(), std::ostream_iterator<std::string>(std::cout, "\n"), [](auto pair) {
return std::to_string(pair.first) + "," + std::to_string(pair.second);
});
}

Live on Godbolt

这里要注意的一点是,你的断言通过了这个 hint无序容器不安全的论点是错误的。当 operator=被调用,一个新元素被插入到容器中, iter成员更新为任何 insert返回。由于此值必须有效,因此 iter 不可能可能永远无效。

关于c++ - std::为无序集(或映射)插入迭代器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27429705/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com