候选函数不可行:第一个参数('const Node *')会丢失const限定符

时间:2015-07-27 22:29:40

标签: c++ class const qualifiers

我正在使用内置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());
}

digraphunordered_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;

因此我认为不应该有编译错误,为什么我会得到一个呢?

1 个答案:

答案 0 :(得分:4)

find()如下所示:find(const T& key)如果TNode*,则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);
}