わかりました、追加された情報から、コンパイラが関数を呼び出さなければならないのに対し、非参照ごとに問題addNode
があるようです(注意してください)。説明させてください:Node_ptr
const
const boost::shared_ptr<Node>&
const
std::set
連想コンテナです。連想コンテナは、キー要素を使用して順序を定義し、要素をある順序で格納します。コンテナが知らないうちにキーを変更できるようにすると、コンテナの内部順序が無効になります。std::set<T>::iterator
そのため、 a を逆参照しても変更可能な左辺値は返されないと私は考えています。(これは、返された参照を変更できないことを意味します。たとえば、イテレータpos
を aに持っている場合は、コンパイルしないstd::set<int>
でください。) これのキャッチは、変更可能な左辺値のみが非参照
にバインドされることです。しかし、返されるものは変更可能な左辺値ではないため、変更されません。(したがって、私の例ではコンパイルされません。)その理由は、これが許可されている場合、その非 - を介してソートキーを変更できるからです。*pos=42
const
*pos
int& r = *pos;
const
コンテナの背後にある参照を参照し、コンテナの内部順序を台無しにします。
そのため、 your *pos
will の結果が a にバインドされませんNode_ptr&
。そしてそれが、コンパイラが関数を呼び出せない理由です。
あなたのaddNode()
メンバー関数は、与えられたノードを本当に変更しますか? そうでない場合は、const Node_ptr&
.
もしそうなら、あなたは設計上の問題を抱えています。セット内の要素を変更することはできません。できることは、セットから削除して変更し、再度追加することだけです。
余談ですが、VC9 は実際に次のコードをコンパイルします。
#include <iostream>
#include <set>
#include <typeinfo>
#include <iterator>
int main()
{
std::set<int> set;
set.insert(5);
std::cout << *set.begin() << '\n';
*set.begin() = 3; // this is an error!
std::cout << *set.begin() << '\n';
return (0);
}
これは VC9 のエラーだと思います。コモーはそれを拒否します。
呼び出す必要があると思われる関数をコンパイラが呼び出さない、またはオーバーロードのセットから間違った関数を呼び出すという謎を解決する方法を次に示します。
あなたが呼び出すべきだと思った関数は ですGraph::addNode(Node_ptr&)
。あなたがそれを呼び出すべきだと思ったコードは
addNode(*pos);
必要な正確なパラメーターを提供するようにそのコードを変更します。
Node_ptr& tmp = *pos;
addNode(tmp);
これで、呼び出しは確実にコンパイルされる (または正しいオーバーロードを呼び出す) ようになり、*pos
を に割り当てることができないとコンパイラが判断した場合、コンパイラは吠える必要がありNode_ptr&
ます。
通常、この戦術は、そのような状況で何が問題なのかを見つけるのに役立ちます。