Я пытаюсь использовать 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"] );
Есть другие идеи?
Вы можете использовать такой функциональный объект для создания элементов карты:
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.)
Других решений пока нет …