1

我正在尝试使用一个std::unordered_map<std::string, std::shared_ptr<CObject>>(在此称为地图)能够使用地图根据其名称在不同对象上调用相同的函数。地图中的函数指针将是一种方法,但我认为将对象本身保存在地图中会更干净。

现在,对象被存储在 a 中shared_ptr,因为它们依赖于其他用法(在函数调用之前自动调用的成员函数等),并且shared_ptr使用 wraps 的函数进行分配make_shared,其中包括重置它,以及捕获和抛出带有添加相关信息的异常(可能不再需要,但它是一个相当大的代码库,并且它是编码标准的一部分)。该函数以shared_ptr为引用分配给定对象,并返回 void。

我想做的是创建一个映射到对象的键映射,并在所有这些对象上调用 allocate 函数。但由于 allocate 函数不返回 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 ) );

我想出的唯一方法是在地图上不存在的值上调用 allocate 函数,map如果它们不存在,它会自动为我创建对象。喜欢:

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

还有其他想法吗?

4

1 回答 1

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());

或者,如果您更喜欢使用 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。)

于 2013-06-27T16:22:50.650 回答