Как вставить rvalue в карту после вызова функции на ней

Я пытаюсь использовать std::unordered_map<std::string, std::shared_ptr<CObject>> (называемый здесь картой), чтобы иметь возможность использовать карту для вызова одних и тех же функций для различных объектов на основе их имени. Указатели функций на карте были бы одним из способов сделать это, но я подумал, что было бы чище сохранить сами объекты на карте.

Теперь объекты хранятся в shared_ptrпоскольку они имеют зависимости от других видов использования (функции-члены, автоматически вызываемые перед вызовами функций и т. д.), и shared_ptr распределяются с помощью функции, которая переносит make_sharedкоторый, помимо прочего, сбрасывает его, а также перехватывает и генерирует исключения с добавлением соответствующей информации (вероятно, больше не нужна, но это довольно большая кодовая база, и это часть стандарта кодирования). Эта функция распределяет данные объекты, беря shared_ptr в качестве ссылки и возвращает недействительными.

Я хотел создать карту с привязкой ключей к объектам и вызвать функцию allocate для всех этих объектов. Но так как функция allocate не возвращает OutputIterator или что-либо подобное, я не могу использовать std::inserter,

Они не хотят этого делать, используя lvalues, например:

std::map<std::string, std::shared_ptr<CObject>> objectMap;
shared_ptr< CObject> object;
allocate< CObject>( object );
objectMap.insert( make_pair("FirstObject", object ) );

Единственный способ, которым я придумал, — это вызвать функцию allocate для несуществующих значений на карте, как map будет автоматически создавать объекты для меня, если они не существуют. Подобно:

std::map<std::string, std::shared_ptr<CObject>> objectMap;
allocate< CObject>( objectMap["FirstObject"] );

Есть другие идеи?

1

Решение

Вы можете использовать такой функциональный объект для создания элементов карты:

struct AllocCObject {
std::pair<const std::string, std::shared_ptr<CObject>>
operator()(const std::string& key) const
{
std::shared_ptr<CObject> p;
allocate<CObject>(p);
return { key, p };
}
};

std::string keys[] =  { "k1", "k2", "k3" };
std::map<std::string, std::shared_ptr<CObject>> map;
std::transform(std::begin(keys), std::end(keys), std::inserter(map), AllocCObject());

Или, если вы предпочитаете использовать лямбду вместо функционального объекта:

auto allocObject = [] (std::string const& s) {
std::shared_ptr<CObject> p;
allocate<CObject>(p);
return std::make_pair(s, p);
}

В качестве альтернативы, несколько ближе к вашей идее (которая мне подходит):

std::map<std::string, std::shared_ptr<CObject>> map = {
{ "k1", {} }, { "k2", {} }, { "k3", {} }
};
for (auto& e : map)
allocate<CObject>(e.second);

(N.B. Я не думаю, что VC ++ поддерживает инициализацию карты из initializer_list так, но это действительно C ++ 11.)

1

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector