由引用传递的迭代器集/映射迭代器不可取消引用

Posted

技术标签:

【中文标题】由引用传递的迭代器集/映射迭代器不可取消引用【英文标题】:iterator passed by reference set/map iterator not dereferencable 【发布时间】:2017-01-20 12:11:47 【问题描述】:

我在通过引用传递迭代器时遇到了一些麻烦。在程序中,我有三个类:包含 std::map> 作为私有成员的类 A。 B 类将 A 类作为私有成员。而类 C 在其构造函数中接收类 B。在类 C 中,我试图检索一个指向映射的迭代器,如下所示:

class A()
   private: 
        std::map<std::vector<>> theMap;
   public:
        void theMap_access() std::string to_access , std::map<std::vector<>>::iterator &it)
        it =  theMap.find(to_access);
        it-> first; //OK
            
;

class B()
   private: 
        A a;
   public: 
        A A_access()return a;
;

class C(B &b)
   public: 
       std::map<std::vector<>>::iterator it;
       std::string to_access = "test";
       B.A_access().theMap_access(to_access, it);
       it-> first; //KO
;

当我执行这段代码时,我确信“测试”在地图中。因此,当我在 A 类中取消引用它时,代码运行良好,我得到它->first = "test"。但是在通过引用将它传递回类 C 之后,我得到了这个错误:set/map iterator not dereferencable。我假设迭代器一旦传回并没有指向它在 A 类中指向的内容。你能解释一下为什么以及如何解决这个问题吗?非常感谢您的帮助。

【问题讨论】:

std::map<:vector>> theMap 。不能编译 map 需要两个模板参数。 B.A_access()C 类中的使用返回A 对象的副本,并且该副本在it-&gt;first 执行之前消失。 但即使我修改代码以返回这样的迭代器:(在 C 类中)它 = B.A_access().theMap_access(to_access);和(在 A 类中)std::map<:vector>>::iterator theMap_access() std::string to_access) it = theMap.find(to_access);归还它; 我面临同样的问题。你知道我该如何解决这个问题并指向 C 类的地图吗?谢谢。 @Eglantine 不,它与迭代器的设置无关。它与A_access 返回的所有内容有关。您错误地使用了A 的副本,而这些副本在该行执行后消失了。 非常感谢,已修复!祝你有美好的一天。 【参考方案1】:

我收到此错误:set/map iterator not dereferencable。

那是因为B.A_access的返回中用到的A对象:

B.A_access().theMap_access(to_access, it);

执行上述行后不再存在。所以你设置的迭代器指的是一个不存在的map,因为那个map也已经消失了。

原因是B.A_access() 返回A 对象的副本,而不是包含您尝试使用的std::map 的实际A 对象。

如果您想使用包含您要操作的std::map 的实际A 对象,那么A_access 应该返回对A 的引用,而不是A 的副本。

所以修复应该是:

 A& A_access()return a;

【讨论】:

以上是关于由引用传递的迭代器集/映射迭代器不可取消引用的主要内容,如果未能解决你的问题,请参考以下文章

输入迭代器是不是只能在赋值的右手符号上被取消引用?

C ++迭代器取消引用和前缀递增/递减样式? *--Iter ok 风格是不是明智?

这段代码在哪里取消引用无效的迭代器? (C++)

传递迭代器值而不是引用函数

通过引用传递 C++ 迭代器有啥问题?

取消引用集合迭代器时将“字符串&”绑定到“常量字符串”时出错