Компараторы в std::map, std::set и std::priority_queue
Все эти три контейнера принимают объект функции по константной ссылке, а не по значению или по ссылке пересылки. Это приводит к необходимости копирования объекта функции во внутреннее хранилище контейнера (не более двух раз).
Есть ли причина дважды копировать функциональный объект? В отличие от предоставления пользователю возможности передавать любой тип функционального объекта и встроить его во внутреннее хранилище функторов? Таким образом, библиотека является более общей, и пользователю меньше сюрпризов.
Та же философия применяется в push_back()
функции - у них есть две перегрузки, одна с константной ссылкой и одна с rvalue ссылкой, потому что это дает пользователю больше контроля над тем, хотят ли они переместить значение или скопировать значение. Библиотека остается эффективной в общем случае, не делая никаких предположений о сценарии использования.
Я подозреваю, что это дизайнерское решение, перенесенное с 11 дней до C++. Будет ли это изменение достойным предложением для стандарта?
1 ответ
Как правило, компаратор - это довольно маленький объект, который дешево копировать, и вы создадите свой контейнер только один раз. Та дополнительная копия за один раз не будет иметь большого значения. Вы, вероятно, не создаете кучу std::map
s в вашем коде, чувствительном к задержке. Так что от введения большего количества конструкторов для этих контейнеров просто нет большой пользы. И как бы выглядело такое предложение? Хотели бы вы взять Allocator
по ссылке? Теперь мы добавляем еще несколько конструкторов. Изменить все конструкторы, принимая Compare const&
вместо этого взять ограниченную пересылку ссылок? Теперь мы сломали ABI для все еще незначительного, если таковые имеются, усиления. Конструкторы сложны. Я даже не уверен, что если std::map
были разработаны сегодня, интерфейс будет выглядеть иначе в этом отношении. Во всяком случае, мы бы просто взять Compare
по значению вместо const&
,
С другой стороны, push_back
используется много, с большим разнообразием типов, во время основного времени выполнения программ. Будучи в состоянии перейти в vector
, или же emplace
в vector
Огромная победа. Две ситуации на самом деле не сопоставимы.