好的,根据您添加的信息,问题似乎是每个非引用addNode
都需要一个,而编译器必须调用该函数的是一个(注意)。让我解释:Node_ptr
const
const boost::shared_ptr<Node>&
const
std::set
是一个关联容器。关联容器以某种顺序存储它们的元素,使用关键元素来定义排序。如果允许您在容器不知情的情况下更改密钥,您将使容器的内部顺序无效。这就是为什么我认为取消引用 astd::set<T>::iterator
不会返回可修改的左值。(这意味着您不能更改返回的引用。例如,如果您有一个指向 a 的迭代器pos
,std::set<int>
则*pos=42
不应编译。)
这样做的问题是只有可修改的左值才会绑定到非const
引用。但是*pos
返回的不是可修改的左值,因此不会。(因此,在我的示例中,int& r = *pos;
不会编译。)原因是,如果允许,您可以通过非const
在容器背后引用并弄乱容器的内部顺序。
这就是为什么你的结果*pos
不会绑定到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&
.
通常这种策略可以帮助我找出在这种情况下出了什么问题。