候选函数不可行:第一个参数('const Node *')将失去常量限定符

candidate function not viable: 1st argument ('const Node *') would lose const qualifier

本文关键字:失去 常量 const 不可行 第一个 参数 候选函数 Node      更新时间:2023-10-16

我正在用内置在unordered_map<Node*, unordered_set<Edge>>数据结构中的c++编写一个diggraph(有向图)类,其中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>>的diggraph的私有成员。

但是,编译器生成以下错误:

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++文档,看到unordered_map容器中的find()方法声明具有const关键字:

std::unordered_map::find
    const_iterator find(const Key& key) const;

所以我认为不应该有编译错误,那么为什么我得到一个?

find()看起来像这样:find(const T& key)如果TNode*,那么Node*必须是const。但是请注意,指针必须是const,而不是containsNode(const Node * n)所指向的值。find()不能保证n所指向的值不会改变,这违反了const Node * n

我的朋友,你的处境是对的。由于键指针,您可能不能使用指向值的副本,不同的地址,也不能将其分配给可以由find使用的非const指针。你可以投,但对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);
}