2013-10-24 5 views
0

У меня есть следующий класс и методы C++. Я пытаюсь получить доступ к частному члену «исходящий» из функции const numOutgoing(). Я смущен о поведении для строк 127-128 против 129-130.Доступ к частному члену в общедоступном методе const

Строка 129: Создание копии, которую можно изменить позже, функция const не заботится Строка 130: Получение ссылки, но vec определяется как const, поэтому все хорошо.

Строка 127: Я предположил, что копия выполняется, но я получаю ошибку компилятора Строка 128: та же ошибка компилятора.

90 class Graph 
91 { 
92   map<int, vector<int> > outgoing; 
93 
95 public: 
96   Graph(const vector<int> &starts, const vector<int> &ends); 
97   int numOutgoing(const int nodeID) const; 
99 }; 
100 
120 
121 int 
122 Graph::numOutgoing(const int nodeID) const 
123 { 
124   if (outgoing.find(nodeID) == outgoing.end()) { 
125     throw invalid_argument("Invalid node Id"); 
126   } 
127   // vector<int> vec = outgoing[nodeID]; 
128   // const vector<int> &vec = outgoing[nodeID]; 
129   vector<int> vec = outgoing.at(nodeID); 
130   // const vector<int> &vec = outgoing.at(nodeID); 
131 
132   return vec.size(); 
133 } 

Я пытаюсь понять, почему линия 127/128 дает мне следующую ошибку компиляции:

./templ.cc:128:42: error: passing 'const std::map<int, std::vector<int> >' as 'this' argument of 'std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const key_type&) [with _Key = int; _Tp = std::vector<int>; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int, std::vector<int> > >; std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type = std::vector<int>; std::map<_Key, _Tp, _Compare, _Alloc>::key_type = int]' discards qualifiers [-fpermissive] 

Ниже приведены прототипы для оператора [] и в методах в классе «карте».

 mapped_type& operator[] (const key_type& k); <====== 
     mapped_type& operator[] (key_type&& k); 

     mapped_type& at (const key_type& k); 
const mapped_type& at (const key_type& k) const; 

Было бы очень признательно, если кто-то может помочь мне понять ошибку компиляции. Может ли проблема быть в том, что operator[] не возвращает тип const? Если да, то operator[] и at не являются эквивалентными, не так ли?

ответ

3

Это потому, что метод

int Graph::numOutgoing(const int nodeID) const 

является const, в то время как operator[] не Const. Это из-за конструктивного решения: если кто-то пытается получить доступ к ключу, который не существует с operator[], он создает его, тем самым изменяя std::map.

Чтобы решить проблему, используйте map<int, vector<int> >::const_iterator result = outgoing.find(nodeID); Тогда, если это не end(), вы можете просто получить доступ к ключу с result->first и значение с result->second.

+0

Если он может использовать C++ 11, то функция 'std :: map :: at()' будет работать, но она с броском, если элемент не найден, поэтому вам понадобится блок try-catch , –

1

Проблема есть оператор [], который является неконстом. Вызывающий может изменять содержимое карты с помощью неконстантной ссылки, которую он возвращает, поэтому этот оператор не помечен как const.

3

Ваша проблема заключается в том, что функция numOutgoing является константой, поэтому она может вызывать только функции const для членов класса. В этом случае действителен только const mapped_type& at (const key_type& k) const;.

Вы также можете оставить const_iterator от outgoing.find(nodeID) и разыменовать это, чтобы получить доступ const к вашему дочернему вектору.

2

Would really appreciate it if someone can help me understand the compilation error. Could the issue be that "operator[]" does not return a "const" type? If so, then "operator[]" and "at" are not equivalent, right?

Да, operator[] и at не эквивалентны вообще.

at всегда будет возвращать значение, поэтому оно может быть const. Если такой элемент не существует, генерируется исключение типа std::out_of_range.

operator[] с другой стороны никогда не будет жаловаться, если нет элементов, поскольку он попытается создать новый.Такое поведение выбрано так:

std::map<int, int> x; 
x[0] = 1; 

возможен.

Смежные вопросы