Есть ли какая-то возможность забрать элемент из std::list одновременно удаляя его (не вызывая отдельно два метода front и pop_front)? Если такого метода или возможности нет, то какова мотивация комитета не добавлять такой метод в стандарт?
// Например сделать так.
auto val = list.take_front();
// Заместо
auto val = list.front();
list.pop_front();
Дело в том, что все стандартные контейнеры спроектированы предоставлять хранилище для хранимых в них объектов. Поддержка возможности забрать какой либо элемент из контейнера потребовала бы необходимости реализовывать поддержку дробления и отчуждения внутреннего хранилища контейнеров, что является делом не тривиальным.
Поддержку же копирования или перемещения существующего элемента можно сделать тривально, например
value_type take_front()
{
auto val{::std::move(front())};
pop_front();
return val;
}
Но, как видите, большой экономии тут бы не вышло.
Возможность добавления и забирания элементов реализуется в интрузивных контейнерах, которые спроектированы не предоставлять хранилище для хранимых в них объектов, а делигировать это пользователю. В этом примере создается только один экземпляр объект t_Item который добавляется, а затем изымается из контейнера не создавая дополнительных экземпляров:
#include <boost/intrusive/list.hpp>
#include <cstdlib>
class tag_ItemListBaseHook;
using t_ItemListBaseHook = ::boost::intrusive::list_base_hook
<
::boost::intrusive::tag<tag_ItemListBaseHook>
, ::boost::intrusive::link_mode<::boost::intrusive::safe_link>
>;
class t_Item final: public t_ItemListBaseHook
{
private: int m_value{22};
};
using t_Items = ::boost::intrusive::list
<
t_Item
, ::boost::intrusive::base_hook<t_ItemListBaseHook>
, ::boost::intrusive::constant_time_size<false>
>;
int main()
{
t_Item item{};
t_Items items{};
items.push_back(item);
items.pop_back();
return EXIT_SUCCESS;
}
Как можно увидеть в описании этого класса, такого метода нет. Хотя во многих языках программирования pop как раз удаляет и сразу возвращает значение (так, например, в JavaScript'e).
Это сделано с целью предотвратить проблемы с памятью. Что, если в списке не число, а объекты кастомного класса? Возвращать ссылку на него? А он может быть уже удалён с вызовом деструктора. Накладывать ограничение на класс, чтобы у него был определён конструктор копирования? Тоже не вариант. Куда проще конечному юзеру класса (т.е, разработчику, Вам) подписать одну строку решения для своей конкретной ситуации.
На enSO несколько лет назад был такой же вопрос про std::queue, там Вы можете найти ещё больше пояснений.
Продвижение своими сайтами как стратегия роста и независимости