Препятствуют ли методы класса const присваивать переменные вне класса? - PullRequest
0 голосов
/ 29 марта 2019

Я решил проблему компиляции этого кода, удалив "const". Однако, почему кажется, что я не могу назначить не принадлежащие классу члены в методе класса const в этой конкретной ситуации? Это, вероятно, является частью класса; хотя я не понимаю почему.

Я получил свой код для компиляции, но я запутался в этой ситуации.

Ниже приведены некоторые объявления в классе.

using twoDList = multimap<string,string>;
twoDList SomeMultiMap;

Это будет работать, когда я снимаю "const". Или хотя бы скомпилировать. Хотя здесь я просто назначаю итераторы, объявленные только в этой функции. Кстати, используя пространство имен std.

bool object::foo(string a, string b) const
{
    pair<object::twoDList::iterator,object::twoDList::iterator> wordRange;
    wordRange = SomeMultiMap.equal_range(a);

    object::twoDList::iterator it = wordRange.first;

    //...
    //...
    //...
}

Я ожидал, что эта функция будет компилироваться без удаления const, но она не компилируется.

Редактировать: вот ошибки компиляции, и я использую это в командной строке Linux.

g++ -g -DDEBUG -std=c++11 -c test1.cpp
In file included from /usr/include/c++/4.8/bits/stl_algobase.h:64:0,
                 from /usr/include/c++/4.8/bits/char_traits.h:39,
                 from /usr/include/c++/4.8/ios:40,
                 from /usr/include/c++/4.8/ostream:38,
                 from /usr/include/c++/4.8/iostream:39,
                 from test1.cpp:1:
/usr/include/c++/4.8/bits/stl_pair.h: In instantiation of ‘std::pair<_T1, _T2>& std::pair<_T1, _T2>::operator=(std::pair<_U1, _U2>&&) [with _U1 = std::_Rb_tree_const_iterator<std::pair<const std::basic_string<char>, std::basic_string<char> > >; _U2 = std::_Rb_tree_const_iterator<std::pair<const std::basic_string<char>, std::basic_string<char> > >; _T1 = std::_Rb_tree_iterator<std::pair<const std::basic_string<char>, std::basic_string<char> > >; _T2 = std::_Rb_tree_iterator<std::pair<const std::basic_string<char>, std::basic_string<char> > >]’:
test1.cpp:15:15:   required from here
/usr/include/c++/4.8/bits/stl_pair.h:188:10: error: no match for ‘operator=’ (operand types are ‘std::_Rb_tree_iterator<std::pair<const std::basic_string<char>, std::basic_string<char> > >’ and ‘std::_Rb_tree_const_iterator<std::pair<const std::basic_string<char>, std::basic_string<char> > >’)
    first = std::forward<_U1>(__p.first);
          ^
/usr/include/c++/4.8/bits/stl_pair.h:188:10: note: candidates are:
In file included from /usr/include/c++/4.8/map:60:0,
                 from test1.cpp:2:
/usr/include/c++/4.8/bits/stl_tree.h:157:12: note: std::_Rb_tree_iterator<std::pair<const std::basic_string<char>, std::basic_string<char> > >& std::_Rb_tree_iterator<std::pair<const std::basic_string<char>, std::basic_string<char> > >::operator=(const std::_Rb_tree_iterator<std::pair<const std::basic_string<char>, std::basic_string<char> > >&)
     struct _Rb_tree_iterator
            ^
/usr/include/c++/4.8/bits/stl_tree.h:157:12: note:   no known conversion for argument 1 from ‘std::_Rb_tree_const_iterator<std::pair<const std::basic_string<char>, std::basic_string<char> > >’ to ‘const std::_Rb_tree_iterator<std::pair<const std::basic_string<char>, std::basic_string<char> > >&’
/usr/include/c++/4.8/bits/stl_tree.h:157:12: note: std::_Rb_tree_iterator<std::pair<const std::basic_string<char>, std::basic_string<char> > >& std::_Rb_tree_iterator<std::pair<const std::basic_string<char>, std::basic_string<char> > >::operator=(std::_Rb_tree_iterator<std::pair<const std::basic_string<char>, std::basic_string<char> > >&&)
/usr/include/c++/4.8/bits/stl_tree.h:157:12: note:   no known conversion for argument 1 from ‘std::_Rb_tree_const_iterator<std::pair<const std::basic_string<char>, std::basic_string<char> > >’ to ‘std::_Rb_tree_iterator<std::pair<const std::basic_string<char>, std::basic_string<char> > >&&’
In file included from /usr/include/c++/4.8/bits/stl_algobase.h:64:0,
                 from /usr/include/c++/4.8/bits/char_traits.h:39,
                 from /usr/include/c++/4.8/ios:40,
                 from /usr/include/c++/4.8/ostream:38,
                 from /usr/include/c++/4.8/iostream:39,
                 from test1.cpp:1:
/usr/include/c++/4.8/bits/stl_pair.h:189:11: error: no match for ‘operator=’ (operand types are ‘std::_Rb_tree_iterator<std::pair<const std::basic_string<char>, std::basic_string<char> > >’ and ‘std::_Rb_tree_const_iterator<std::pair<const std::basic_string<char>, std::basic_string<char> > >’)
    second = std::forward<_U2>(__p.second);
           ^
/usr/include/c++/4.8/bits/stl_pair.h:189:11: note: candidates are:
In file included from /usr/include/c++/4.8/map:60:0,
                 from test1.cpp:2:
/usr/include/c++/4.8/bits/stl_tree.h:157:12: note: std::_Rb_tree_iterator<std::pair<const std::basic_string<char>, std::basic_string<char> > >& std::_Rb_tree_iterator<std::pair<const std::basic_string<char>, std::basic_string<char> > >::operator=(const std::_Rb_tree_iterator<std::pair<const std::basic_string<char>, std::basic_string<char> > >&)
     struct _Rb_tree_iterator
            ^
/usr/include/c++/4.8/bits/stl_tree.h:157:12: note:   no known conversion for argument 1 from ‘std::_Rb_tree_const_iterator<std::pair<const std::basic_string<char>, std::basic_string<char> > >’ to ‘const std::_Rb_tree_iterator<std::pair<const std::basic_string<char>, std::basic_string<char> > >&’
/usr/include/c++/4.8/bits/stl_tree.h:157:12: note: std::_Rb_tree_iterator<std::pair<const std::basic_string<char>, std::basic_string<char> > >& std::_Rb_tree_iterator<std::pair<const std::basic_string<char>, std::basic_string<char> > >::operator=(std::_Rb_tree_iterator<std::pair<const std::basic_string<char>, std::basic_string<char> > >&&)
/usr/include/c++/4.8/bits/stl_tree.h:157:12: note:   no known conversion for argument 1 from ‘std::_Rb_tree_const_iterator<std::pair<const std::basic_string<char>, std::basic_string<char> > >’ to ‘std::_Rb_tree_iterator<std::pair<const std::basic_string<char>, std::basic_string<char> > >&&’
makefile:10: recipe for target 'test1.o' failed
make: *** [test1.o] Error 1

Редактировать: больше правок для исправления операторов области. Кроме того, добавил тот факт, что я использую пространство имен std, если это помогает.

1 Ответ

1 голос
/ 30 марта 2019

A const после списка параметров функции-члена - обещание не изменять объект класса с помощью указателя this. Тип this становится const ClassType* вместо ClassType*. (Как и любой указатель на констант или ссылка на констант, это означает только то, что вещь нельзя изменить с помощью этого указателя или ссылки, а не то, что объект постоянно является константным или не может быть изменен другими средствами.)

Сказать, что объект класса обрабатывается как const, означает, что все его члены (кроме любых отмеченных mutable) рассматриваются как const. И поскольку в определении функции-члена простое нестатическое имя члена N фактически означает то же самое, что и this->N, члены, названные таким образом, обрабатываются как const, когда объявление функции имеет const после списка параметров.

Так внутри bool object::foo(string a, string b) const имя SomeMultiMap, являющееся членом object, рассматривается как const SomeMultiMap. И equal_range дает pair<const_iterator, const_iterator>, когда выражение объекта multimap равно const, или pair<iterator, iterator>, только когда выражение объекта не равно const.

Так что это может сработать (в зависимости от того, что вам нужно делать потом):

std::pair<twoDList::const_iterator,twoDList::const_iterator> wordRange;
wordRange = SomeMultiMap.equal_range(a);

twoDList::const_iterator it = wordRange.first;

(Обратите внимание, что обычно вам не нужны префиксы object::, поскольку тело функции-члена находится в области видимости своего класса.)

Хотя я бы просто определил эти переменные с помощью auto, избегая необходимости точно определять тип и экономя при наборе этих длинных имен итераторов.

auto wordRange = SomeMultiMap.equal_range(a);
auto it = wordRange.first;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...