我正在尝试使用 std::unordered_map<std::string, std::shared_ptr<CObject>>
(以下简称map)能够使用map根据名称在不同的对象上调用相同的函数。映射中的函数指针是一种方法,但我认为将对象本身保存在映射中会更清晰。
现在,对象存储在 shared_ptr
中,因为它们依赖于其他用法(在函数调用之前自动调用成员函数等),并且 shared_ptr
使用包装 make_shared
的函数进行分配,其中包括重置它,以及捕获并抛出异常并添加相关信息(可能不再需要,但它是一个相当大的代码库,并且它是编码标准的一部分)。此函数通过获取 shared_ptr
来分配给定的对象作为引用,并返回 void。
我想做的是创建一个映射,其中键映射到对象,并在所有这些对象上调用分配函数。但是由于分配函数不返回 OutputIterator 或类似的东西,我无法使用 std::inserter
.
我不想这样做的方式是使用左值,例如:
std::map<std::string, std::shared_ptr<CObject>> objectMap;
shared_ptr< CObject> object;
allocate< CObject>( object );
objectMap.insert( make_pair("FirstObject", object ) );
我想到的唯一方法是对 map 上不存在的值调用分配函数,如map
如果它们不存在,会自动为我创建对象。喜欢:
std::map<std::string, std::shared_ptr<CObject>> objectMap;
allocate< CObject>( objectMap["FirstObject"] );
还有其他想法吗?
最佳答案
您可以使用这样的函数对象来创建 map 元素:
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());
或者如果您更喜欢使用 lambda 而不是函数对象:
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);
(注意,我认为 VC++ 不支持从这样的 initializer_list
初始化映射,但它是有效的 C++11。)
关于c++ - 如何在调用函数后将右值插入映射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17347973/