質問

これは基本的なポインターの質問ですが、これはしばらくの間私を困惑させています。 C ++を使用して、加重グラフを実装しました map 次のように基礎となるデータストラクチャとして:

std::map<int, std::vector<Edge> > edgeList;

このマップには、ノードIDが保持されます(an int)このノードのキーとエッジのリストとして vector 値として

次のように、各ノードのエッジリストを初期化しました。

for(int i = 0; i< n; i++){
        std::vector<Edge> vi;
        edgeList.insert(std::make_pair(i,vi)); // initialize with empty vector (at least, that's the intent)
    }

ここで、グラフにエッジを追加しているときに、エッジリストを取得しようとすると vector 次のように各ノードに対応しています。

std::vector<Edge> vList = edgeList.at(v); // v is the node id here

空っぽ vector VLISTは返されますが、以前にそのVLISTにエッジを追加しました。

一方で、

std::vector<Edge> &vList = edgeList.at(v);

私の目的のためにうまく機能しているようです。なぜ最初の実装が機能しないのか、2番目の実装が行われない理由を説明できますか?

編集:グラフにエッジを追加するためのコードは次のとおりです。

void Graph::addEdge(Edge e){

    // retrieve start and end node for this edge
    int v = e.either(); // returns either end of the edge
    int w = e.other(v);

    // retrieve edge lists for these nodes
    std::vector<Edge> vList = edgeList.at(v); // doesn't work
    std::vector<Edge> wList = edgeList.at(w); // doesn't work

    // add this edge to the list of edges
    vList.push_back(e);
    wList.push_back(e);
}
役に立ちましたか?

解決

std::map::at 関数は、次の参照を返します std::vector 指定されたインデックスで。これを非参照変数に割り当てると、ベクトルのコピーを作成します。挿入操作は、ベクトルのコピーに載っています。ベクターのコピーは、メソッドの最後に範囲外になり、マップにぴったりのベクトルが幸せで影響を受けていません。

代わりに、追加する場合 &, 、 それから vList マップに保存されている実際のベクトルのエイリアスになります。今、変更された変更 vList マップ要素に実際に作られています。必要に応じて、参照を変装したポインターとして見ることができます。その場合、あなたは明示的に書くでしょう

std::vector<Edge> *vList = &edgeList.at(v);

たとえば、そうではありません

std::vector<Edge> *vList = new std::vector();
*vList = edgeList.at(v);

実際、次の例はポイントをより明確に示しています。

using namespace std;

int i = 0;

int& get_i()
{
    return i;
}

int main()
{
   cout << "i = " << i << ", &i = " << &i << endl;

   int j = get_i();
   j++;
   cout << "i = " << i << ", j = " << j << ", &j = " << &j << endl; 

   int& k = get_i();
   k++;
   cout << "i = " << i << ", k = " << k << ", &k = " << &k << endl; 

   return 0;
}

他のヒント

あなたがこれをするとき:

std::vector<Edge> vList = edgeList.at(v);

あなたはAを作成しています コピー マップ内のベクトルの。

あなたがこれをするとき:

std::vector<Edge> &vList = edgeList.at(v);

あなたはそのベクトルへの参照を取得しています。

コピーに要素を追加すると、マップに追加されることはありません(単なるコピーであり、オリジナルとは関係がないため)。参照に要素を追加すると、同じベクトルであるため、マップに追加されます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top