1

std::unordered_map<std::string, std::shared_ptr<CObject>>名前に基づいて異なるオブジェクトで同じ関数を呼び出すためにマップを使用できるように、(ここではマップと呼びます) を使用しようとしています。マップ内の関数ポインターはそれを行う 1 つの方法ですが、オブジェクト自体をマップに保存する方がクリーンだと思いました。

現在、オブジェクトはshared_ptr他の使用法 (関数呼び出しの前に自動的に呼び出されるメンバー関数など) からの依存関係があるため、 に格納され、shared_ptrをラップする関数を使用して割り当てられmake_sharedます。関連情報を追加して例外をスローします (おそらくもう必要ありませんが、かなり大きなコード ベースであり、コーディング標準の一部です)。この関数は、 を参照して指定されたオブジェクトを割り当て、shared_ptrvoid を返します。

私がやりたかったのは、キーがオブジェクトにマッピングされたマップを作成し、それらすべてのオブジェクトで割り当て関数を呼び出すことでした。しかし、割り当て関数は 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です。オブジェクトが存在しない場合は自動的にオブジェクトを作成します。お気に入り:

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

または、関数オブジェクトの代わりにラムダを使用する場合:

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 に答える