1

これが私の質問のおおよそのコードです。まず、コンストラクターを持つ構造体があります。

struct Pair{
Pair(int a, int b): (first (a) , second (b) ) {}
int first;
int second;
};

マップで使用される

map<string, Pair> mymap;

このマップを関数で初期化したい

void f(map<string, Pair>* mymap, string c,int x, int y )
{
(*mymap)[c]=Pair(x,y);
}

しかし、コンパイラは最初に適切なコンストラクターが見つからなかったと言い、次の行はコンストラクターに十分な引数が提供されていないことを示しています。

私の友人は、関数を次のように書くべきだと私に言いました:

void f(map<string, Pair>& mymap, const string& c,int x, int y )
{
  if (mymap.find(c) != mymap.end()) {
    mymap[c] = Pair(x,y);
   }
}

しかし、ここでType *の代わりにType&を使用する理由を説明できませんでした。この点を明確にしたいと思います。誰でも説明できますか?

4

4 に答える 4

3

問題はoperator[]、マップでは、値の型がデフォルトで構築可能である必要があることです。Pairをデフォルトで構築可能にしたくない場合は、次の使用を避ける必要がありoperator[]ます。

void f(map<string, Pair>& mymap, string c,int x, int y )
{
   mymap.insert( std::make_pair(c,Pair(x,y)) );
}

あなたは友達が提案したことを誤解しているかもしれません。の問題は、新しい要素を作成する必要がある場合operator[]にデフォルトのコンストラクターが必要になることではなく、必要になる場合に備えて必要になることです。つまり、要素が事前に存在するかどうかは問題ではありません。


更新することも意図している場合は、そのオプションも考慮する必要があります。

void f(map<string, Pair>& mymap, string c,int x, int y )
{
   auto res = mymap.insert( std::make_pair(c,Pair(x,y)) );
   if ( !res.second )
      res.first->second = Pair(x,y);
}

基本的に、この操作は、キーを指すイテレータと、これがオブジェクトを作成したのか、それとも既にそこにあったのか (この場合、マップ内の値は変更されていません)insertを示す bool のペアを返します。insert結果を保存することでテストinsertでき、値が作成されなかった場合は、返されたイテレータを介して値を更新できます。

于 2012-07-27T16:03:04.043 に答える
2

マップで呼び出すoperator[]には、型がデフォルトで構築可能である必要があります。map::insertまたはmap::emplaceを使用してこれを回避できます

于 2012-07-27T16:01:47.277 に答える
2

デフォルトのコンストラクターが必要です。

Pair(): first () , second () {}

これはマップの に必要であり、 存在しないキーで呼び出されたときにoperator[]デフォルトで構築されたものを作成します。mapped_type

厳密な弱い順序付けを実装する小なり演算子:

struct Pair {
  // as before
  bool operator<(const Pair& rhs) const {
     / some code to implement less-than
  }
};

または、3 番目のテンプレート引数として厳密で弱い順序付けを実装する比較ファンクターまたは関数を渡すことができます。

于 2012-07-27T16:03:42.793 に答える
0

標準コンテナにはデフォルトのコンストラクタが必要です。彼らはoperator=、建設後のある時点で正しい値を設定するためにを使用します。

于 2012-07-27T15:58:28.653 に答える