【问题标题】:Can't dereference the mapped_type of a map const iterator无法取消引用 map const 迭代器的 mapped_type
【发布时间】:2012-07-26 20:47:36
【问题描述】:

鉴于 Visual Studio 2010 中的代码:

void Foo::Bar() const
{
    map_t::const_iterator iter(my_map_.find(key));

    if(my_map_.end() != iter)
        DoStuff(iter->second);
}

Do stuff 将按值获取 mapped_type。映射类型是可复制、可移动、可分配的类型。

我在尝试访问第二个时收到无法复制键/值对的错误消息。即使我自己写:

iter->second;
(*iter).second;

确保它与 DoStuff 无关...

我假设迭代器在返回 operator-> 或 operator* 之前复制了键/值对。

如何获取映射类型的副本?

编辑:

地图本身是无符号短裤,以提升变体,大致如下:

typedef struct{} empty_t;
typedef boost::variant<empty_t, double, long, some POD types> variant_t;
typedef std::map<unsigned short, variant_t> map_t;

然后作为类的私有成员:

map_t my_map_;

需要明确的是,问题不在于传递给 DoStuff。我可以删除该行,然后简单地取消引用迭代器并访问第二个,这将导致编译器错误。

if(my_map_.end() != iter)
        iter->second; //Doesn't do anything, but illustrates the error.

【问题讨论】:

  • 你能发布出现这个问题的代码吗?
  • 如果T = std::map&lt;K, T&gt;,那么T::value_type就是std::pair&lt;const K, V&gt;。注意常量。
  • 正确,但我不要K,我要V。
  • 您确定variant_t 类型仅包含POD 类型吗?我没有通过根据您的代码 sn-ps 拼凑我自己的示例并填写一些空白来重现这一点。我认为您可能需要按照 Luchian Grigore 的建议发布一个独立的复制示例。或者至少复制/粘贴相关的错误消息,这应该比“无法复制键/值对”提供更多详细信息。

标签: c++ visual-c++ stl map iterator


【解决方案1】:

编辑 由于 boost::variant 导致给定问题更新的答案无效(一旦剩余问题信息可用,将使用最终答案更新)。

如果 DoStuff 通过引用或值获取它的变量,并且您直接从 const_iterator 传递变量,则 DoStuff 必须具有 const 引用或 const 值重载函数调用(除非对象类型具有默认的 const 到 non-const转换可用)。否则编译器会抱怨,因为您将 const 元素视为非常量。

另一种选择是将 iter->second 分配给另一个变量(根据元素类型通过构造函数或赋值)并将其传递给 DoStuff ——但最好定义函数的 const 重载版本。

【讨论】:

  • 我在原帖中提到过,但也许我并不清楚。我可以完全删除 DoStuff 行。如果正文只包含迭代器声明和“iter->second;”,那么那里的那一行会给我错误消息。因此,此时分配给本地 mapped_type 是无关紧要的。我将编辑原始帖子以添加说明。 DoStuff 是按值传递的,顺便说一句。
  • 好的,所以你之前没有提到你在使用 boost::variant ——如果你使用一个变体实例的映射,你会遇到同样的错误吗?尝试使用“typedef long variant_t;”并查看错误是否仍然存在。如果它消失了,我认为您的问题是迭代器无法取消引用变体类型,您可能需要通过 StaticVisitor 类对迭代器引用进行包装以处理各种情况(boost.org/doc/libs/1_35_0/doc/html/variant/…
【解决方案2】:

我想通了。

WAYYYYY 远离这段代码,以及一些深入的抽象,映射的迭代器被传递给 std::partition!看来你不能对地图进行分区。

我将地图的内容复制到本地向量中并从那里继续处理,它清除了所有错误消息。

我不知道为什么编译器会变得如此混乱。问题代码在某个完全不相关的地方。不过没关系。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-07-03
    • 2016-06-25
    • 1970-01-01
    • 1970-01-01
    • 2019-02-08
    • 1970-01-01
    • 1970-01-01
    • 2015-01-13
    相关资源
    最近更新 更多