我正在使用内置unordered_map<Node*, unordered_set<Edge>>
数据结构的c ++编写DiGraph(有向图)类,其中Node和Edge是我自己定义的两个结构。在课堂上我写了一个containsNode()
方法来搜索图中是否有Node
。这是containsNode()
方法正文:
bool DiGraph::containsNode(const Node * n) const {
auto::const_iterator it = digraph.find(n);
return (it == digraph.end());
}
digraph
是unordered_map<Node*, unordered_set<Edge>>
类型的DiGraph的私人成员。
但是,编译器会生成以下错误:
error: no matching member function for call to 'find'
auto::const_iterator it = digraph.find(n);
candidate function not viable: 1st argument ('const Node *') would lose const qualifier
const_iterator find(const key_type& __k) const {return __t...
但是,如果我将方法声明为
bool DiGraph::containsNode(Node* n) const {...}
(唯一的区别是从参数列表中删除了const
关键字),然后没有编译错误。
我查看了C ++文档,发现find()
容器中的unordered_map
方法声明包含const
关键字:
std::unordered_map::find
const_iterator find(const Key& key) const;
因此我认为不应该有编译错误,为什么我会得到一个呢?
答案 0 :(得分:4)
find()
如下所示:find(const T& key)
如果T
为Node*
,则Node*
必须为const
。但是请注意,指针必须是const
,而不是containsNode(const Node * n)
给你的值。 find()
无法保证n
指向的值不会受到影响,并且会违反const Node * n
。
你是一个正确的泡菜,我的朋友。由于您的密钥是指针,您可能无法使用指向的值的副本,不同的地址,也无法将其分配给非const
指针,由find使用。你可以投,但尊重const
!重新思考你是如何做到这一点的,是我的建议。
使用集合更容易可视化。开销更少,结果相同。
#include <set>
using namespace std;
class A
{
};
set<A*> test;
void func1(A *const a) // pointer is const
{
test.find(a); //Compiles, but not what you want.
A b;
a = &b; // Doesn't compile. Can't change where a points
*a = b; // compiles. Value at a is open game
}
void func2(const A * a) // value is const
{
test.find(a); //doesn't compile
A b;
a = &b; // compiles. Can change where a points
*a = b; // does not compile. Can't change what a points at
test.find((A*)a); //Compiles, but holy super yuck! Find a better way!
}
int main()
{
A a;
func1(&a);
func2(&a);
}