Я обнаружил, что std::inserter
на std::map<T, C>
не всегда соблюдает пользовательский компаратор, а скорее иногда возвращается к значению по умолчанию operator<
/ std::less
.У кого-нибудь есть опыт с тем, почему это может быть?Я чувствую, что это может быть ошибка компилятора, учитывая спорадический характер.В частности, у меня есть такая функция:
template <typename T, typename C>
std::set<T, C> operator|(const std::set<T, C> &lhs, const std::set<T, C> &rhs)
{
std::set<T, C> out;
std::set_union(lhs.begin(), lhs.end(),
rhs.begin(), rhs.end(),
inserter(out, out.end()));
return out;
}
Но это не всегда использует мой собственный компаратор C
, и иногда (я знаю, я тоже хотел бы найти образец) просто используюstd::less
вместо.Если я заменю его на maunal-конструкцию std::insert_iterator<std::set<T, C>>
, все будет работать правильно:
template <typename T, typename C>
std::set<T, C> operator|(const std::set<T, C> &lhs, const std::set<T, C> &rhs)
{
std::set<T, C> out;
std::set_union(lhs.begin(), lhs.end(),
rhs.begin(), rhs.end(),
std::insert_iterator<std::set<T, C>>(out, out.end()));
return out;
}
Я чувствую, что это может быть ошибкой компилятора (gcc версии 7.3.0), потому что ссылка доступна на http://en.cppreference.com/w/cpp/iterator/inserter описывает inserter
для простого делегирования insert_iterator
:
template< class Container >
std::insert_iterator<Container> inserter( Container& c, typename Container::iterator i )
{
return std::insert_iterator<Container>(c, i);
}
Кроме того, официальный стандарт C ++, раздел 24.5.2.5 (доступен через http://www.open -std.org /jtc1 / sc22 / wg21 / docs / paper / 2013 / n3690.pdf , стр. 859) определяет определение вставщика как возвращающее итератор вставки того же типа, который передан в первом аргументе:
template <class Container>
insert_iterator<Container> inserter(Container& x, typename Container::iterator i);
Что здесь явно не происходит, поскольку возвращаемое insert_iterator
относится к классу типа std::set<T, C = std::less<T>>
, а не std::set<T, C>
.
Существует ли объяснение этому, кроме ошибки компилятора?