Я пишу класс DiGraph (направленный граф) со встроенным в C ++ unordered_map<Node*, unordered_set<Edge>>
структура данных, где Node и Edge — две структуры, которые я определил сам. И в классе я написал containsNode()
метод поиска, если Node
находится на графике. Это containsNode()
тело метода:
bool DiGraph::containsNode(const Node * n) const {
auto::const_iterator it = digraph.find(n);
return (it == digraph.end());
}
digraph
является закрытым членом DiGraph типа unordered_map<Node*, unordered_set<Edge>>
,
Однако компилятор генерирует следующую ошибку:
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;
Поэтому я думаю, что не должно быть ошибки компиляции, так почему я получаю ее?
find()
выглядит так: find(const T& key)
Если T
является Node*
, затем Node*
должно быть const
, Но обратите внимание, что указатель должно быть const
, НЕ значение, на которое указано containsNode(const Node * n)
дам тебе. find()
не даст никаких гарантий, что значение, на которое указывает n
останется нетронутым, и это нарушает const Node * n
,
Вы в правильном рассоле, друг мой. Так как твой ключ является указатель, вы, вероятно, не можете использовать копию указанного значения, другой адрес, а также вы не можете назначить его не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);
}