【问题标题】:C++ STL unordered_map iterator problemC++ STL unordered_map 迭代器问题
【发布时间】:2011-03-14 11:39:28
【问题描述】:
class Demo {
    struct FileData {
      int size;
      BYTE* buffer;
      DWORD flags;
    };

    typedef std::tr1::unordered_map<std::wstring,FileData> FileMap;
    FileMap m_fileMap;

    void myFunc()
    {
      std::wstring name = L"TestFile.png";
      FileMap::const_iterator iter = m_fileMap.find(name);
      std::cout << iter->first;
    }
};

看看上面的代码。我的问题是 FileMap::const_iterator 是如何工作的。 它是否会复制 key(std::wstring) 和 value(FileData)?还是它只是保存指向键和值的指针/引用?

【问题讨论】:

    标签: c++ stl iterator unordered-map


    【解决方案1】:

    迭代器是可赋值的,虽然映射中的键和值必须是可复制的,但它们不需要是可赋值的。

    因此在一般情况下它不能使用副本,它必须在内部保存一个指针或引用。

    在某些情况下,例如整数,它可能会专门化并使用副本。

    【讨论】:

      【解决方案2】:

      它是一个关联的容器:
      这意味着它在内部存储 Key/Value 对(称为 value_type)。

      提供的迭代器重载了 * 和 -> 运算符,以提供对 value_type 的引用。这是一个 std::pair

      因此你可以试试这个:

      FileMap::const_iterator iter = m_fileMap.find(name);
      if (iter != m_fileMap.end())
      {
          FileMap::value_type const&   value = *iter;
      
          FileMap::key_type   const&   key   = iter->first;  /* value.first  */
          FileMap::data_type  const&   data  = iter->second; /* value.second */
      
          // Alternatively:
          // Assuming this hold: typedef std::tr1::unordered_map<std::wstring,FileData> FileMap;
          std::wstring const&    key1  = iter->first;
          FileData     const&    data1 = iter->second;
      }
      

      【讨论】:

      • 嗯,我知道如何使用它们。但在幕后,迭代器如何管理资源? iter->first 是否是 std::wstring 的副本(这里的关键)?因为如果这样做,就会损害性能。
      • @Morris: no operator -> 返回一个指向“value_type”的指针,它有两个成员(第一个,第二个)。由于它是对“value_type”的引用,因此不会复制任何键(除非您明确复制(例如通过分配给变量))。 PS 大多数 STL 实现都经过优化,因此字符串复制相对便宜。
      • 现在我明白了所有的东西。容器将内容存储在其中作为 value_types。迭代器是(就像)指向 value_type 的指针。所以不会涉及任何副本。
      • @Morris:正确。迭代器被设计成“行为”完全像一个指针。
      【解决方案3】:

      没有保证。但是,迭代器很有可能持有指针。如果你使用可变迭代器,你可以修改数据,所以没有复制,我想不出在使用 const 版本时复制的理由。

      但是,您的代码是基于这些考虑还是只是出于好奇?

      【讨论】:

      • 嗯,其实我只是好奇它是如何工作的。这样我就可以确定使用std::tr1::unordered_map&lt;std::wstring,FileData&gt; fileMap; 是有效的,因为它不会复制键和值。
      • 你不应该考虑太多。编译器会优化出很多副本。因此,在许多情况下,避免复制会导致代码复杂,并且可能会因为编译器丢失而变慢并且无法优化。
      【解决方案4】:

      iterator & const_iterator 持有一个指向你的数据的指针。如果找不到您的值,它应该在此处返回 m_fileMap.end()。

      【讨论】:

        【解决方案5】:

        unordered_map 持有一对键\值(按值),const_iterator 持有指向该对的指针。您可以通过 ->.

        访问其成员来取消引用迭代器

        【讨论】:

          猜你喜欢
          • 2011-02-24
          • 2010-12-15
          • 2016-07-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-05-01
          • 2014-08-13
          • 1970-01-01
          相关资源
          最近更新 更多