Компиляция следующего кода (последняя версия MSVC C++) с использованием std::unordered_map, но без нового boost:unordered_flat_map:
#include "boost/unordered/unordered_flat_map.hpp"
#include <unordered_map>
class Foo
{
public:
Foo() = default;
explicit Foo(int x) : m_x_(x) {};
private:
int m_x_;
std::mutex mtx;
};
int main(int argc, char** argv)
{
boost::unordered_flat_map<int,Foo> map_test; //compile with std::unordered_map
map_test.try_emplace(1,1);
return 0;
}
Я не ожидаю, что он будет работать с flat_map как с std::map , предполагая, что карта нуждается в переупорядочении, элементы должны иметь возможность перемещаться/копироваться. Но я не понимаю, почему он работает с unordered_map, а не с boost:unordered_flat_map.
Где документировано это ограничение? Кроме того, ошибка компиляции очень загадочна, неужели вообще нет использования концепций?
концепции появляются с C++20. Требуется некоторое время, прежде чем библиотека сможет перейти к их использованию, особенно такая большая, как boost. Кроме того, некоторые из наиболее важных функций C++20 еще не реализованы должным образом, поэтому пройдет некоторое время, прежде чем сообщество начнет использовать его, за исключением некоторых небольших проектов.
Ведущим фактором является не то, использует ли контейнер упорядоченную организацию хранения. Это не так, как если бы коллекция была переупорядочена (поскольку ключевые свойства неизменяемы, компаратор фиксирован и должен быть ссылочно прозрачным/идемпотентным).
Вместо этого ведущим фактором является то, как распределяется борьба. Плоские карты называются плоскими, потому что они помещают свои элементы в плоскую область, как вектор. Это вызывает перераспределение по мере роста контейнера.
Короче говоря, перемещение требуется при перераспределении. Напротив, и std::map, и std::unordered_map являются контейнерами на основе узлов, т. е. они выполняют выделение для каждого элемента (завернутого в узлы, которые могут содержать дополнительные метаданные).
В контейнерах на основе узлов элементы не нужно перемещать, даже если их отношение внутри контейнера случайно. Это также то, что дает контейнерам на основе nude их характеристики стабильности ссылок/итераторов.
В дополнение к перераспределению, плоские контейнеры могут нуждаться в перемещении элементов при вставке/удалении, чтобы сохранить неизменность порядка.
Вы поняли эту часть, но обратное неверно из-за требований перераспределения.
Это должно работать с
boost::unordered_map
, но не сboost::unordered_flat_map
. Я полагаю, что последнее требует движения объекта, чтобы он оставался плоским.