无法在 const 成员函数中分配多图迭代器私有多图成员开始

Cannot Assign multimap iterator private multimap member begin in const member function

我正在尝试在 public 成员函数中遍历多重映射,它是我的 class 的私有成员,因此我可以遍历多重映射并打印元素。我知道如果我在非 const 下创建打印函数,它就可以工作,但我不能完全理解为什么它不能与 const 一起工作。我假设分配迭代器 (my_map.begin()) 允许修改 multimap 但 const 修饰符不允许这样做,因此代码不会 compile.Can 任何人给我一个清晰和关于为什么这不适用于 const 函数的更深入的解释?我对使用 STL 容器相当陌生,只是想更深入地了解它们的功能。感谢大家的帮助。 (下面的 C++ 代码) (P.S。为了尽可能清楚,我不是在问如何遍历多图。再次感谢。)

#include <iostream>
#include <iterator>
#include <string>
#include <map>

// Synonymous types for my  multimap and multimap iterator
typedef std::multimap<int, std::string> mm;
typedef mm::iterator mit;

class Foo
{
private:
  mm my_map;
  static int count;

public:
  Foo() {}
  void add(const std::string&);
  void print() const;
};

int Foo::count = 0;

void Foo::add(const std::string& s)
{
  my_map.insert(std::make_pair(count++, s));
}

**// This is the implementation of the that breaks my code**
void Foo::print() const
{
  mit it = my_map.begin(); // **I do not fully understand why this does not work.**
}

如果你想在const函数中得到一个迭代器那么你不能使用iterator,而必须使用const_iterator 代替。所以你必须改变 mit 类型:

typedef mm::const_iterator mit;

这里是编译和运行: https://godbolt.org/z/jM4rK6556

或者另一种方法是不强制类型并让它推断它想要的任何东西,通过更改打印中的行:

auto it = my_map.begin();

这是 运行 的版本: https://godbolt.org/z/rTv6xqPqq

对于未来,如果您将遇到的错误包括在问题中,以便其他人知道并且更容易google,那就更好了。即使阅读错误也会提示正在发生的事情:

<source>: In member function 'const void Foo::print() const':
<source>:31:24: error: conversion from 'std::multimap<int, std::__cxx11::basic_string<char> >::const_iterator' {aka 'std::_Rb_tree<int, std::pair<const int, std::__cxx11::basic_string<char> >, std::_Select1st<std::pair<const int, std::__cxx11::basic_string<char> > >, std::less<int>, std::allocator<std::pair<const int, std::__cxx11::basic_string<char> > > >::const_iterator'} to non-scalar type 'mit' {aka 'std::_Rb_tree<int, std::pair<const int, std::__cxx11::basic_string<char> >, std::_Select1st<std::pair<const int, std::__cxx11::basic_string<char> > >, std::less<int>, std::allocator<std::pair<const int, std::__cxx11::basic_string<char> > > >::iterator'} requested
   31 |   mit it = my_map.begin();
      |            ~~~~~~~~~~~~^

所以说比较类型时不能从类型A转换为类型B,区别很明显,这里是类型A:

std::multimap<int, std::__cxx11::basic_string<char> >::const_iterator

所以你的 mit 类型与 my_map.begin() 返回的不匹配。