Вы можете использовать собственный функтор вместо std::inserter
и повторно вызывать out.end()
каждый раз, когда вставляется новый элемент .
В качестве альтернативы, если ваши значения отсортированы по убыванию, подойдет out.begin()
.
Я выбрал ответ Александра Гесслера как «правильный», потому что он привел меня к этому решению, которое, как я думал, я все равно опубликую. Я написал last_inserter()
, который гарантирует, что позиция вставки всегда является итератором для последнего элемента (или begin(), если он пуст), потому что set
хочет, чтобы итератор элемент , предшествующий фактической позиции вставки для лучшей производительности (поэтому не end() - это будет единица после фактической позиции вставки).
Использование в соответствии с исходным примером выглядит следующим образом:
std::set<int> s1, s2, out;
// ... s1 and s2 are populated ...
std::set_intersection(s1.begin(), s1.end(),
s2.begin(), s2.end(),
last_inserter(out)); // note no iterator provided
Это гарантирует, что подсказка вставки всегда является итератором для последнего элемента, что, как мы надеемся, обеспечивает наилучшую производительность при использовании выходного итератора для набора с отсортированным диапазоном. , как указано выше.
Ниже приведена моя реализация. Я думаю, что это зависит от платформы для реализации STL в Visual C++ 2010, потому что он в значительной степени основан на существующем insert_iterator
, и я могу заставить его работать, только наследуя от std::_Outit
. Если кто-нибудь знает, как сделать это переносимым, дайте мне знать:
// VC10 STL wants this to be a checked output iterator. I haven't written one, but
// this needs to be defined to silence warnings about this.
#define _SCL_SECURE_NO_WARNINGS
template<class Container>
class last_inserter_iterator : public std::_Outit {
public:
typedef last_inserter_iterator<Container> _Myt;
typedef Container container_type;
typedef typename Container::const_reference const_reference;
typedef typename Container::value_type _Valty;
last_inserter_iterator(Container& cont)
: container(cont)
{
}
_Myt& operator=(const _Valty& _Val)
{
container.insert(get_insert_hint(), _Val);
return (*this);
}
_Myt& operator=(_Valty&& _Val)
{
container.insert(get_insert_hint(), std::forward<_Valty>(_Val));
return (*this);
}
_Myt& operator*()
{
return (*this);
}
_Myt& operator++()
{
return (*this);
}
_Myt& operator++(int)
{
return (*this);
}
protected:
Container& container;
typename Container::iterator get_insert_hint() const
{
// Container is empty: no last element to insert ahead of; just insert at begin.
if (container.empty())
return container.begin();
else
{
// Otherwise return iterator to last element in the container. std::set wants the
// element *preceding* the insert position as a hint, so this should be an iterator
// to the last actual element, not end().
return (--container.end());
}
}
};
template<typename Container>
inline last_inserter_iterator<Container> last_inserter(Container& cont)
{
return last_inserter_iterator<Container>(cont);
}