代码之家  ›  专栏  ›  技术社区  ›  Frank

如何使集合迭代器的行为类似于映射迭代器?

  •  5
  • Frank  · 技术社区  · 13 年前

    Foo 包含 map 并提供 begin() end() 迭代函数:

    class Foo {
      typedef std::map<int, double> Container;
      typedef Container::const_iterator const_iterator;
      Container c_;
     public:
      const_iterator begin() const { return c_.begin(); }
      const_iterator end() const { return c_.end(); }
      void insert(int i, double d) { c_[i] = d; }
      // ...
    
    };
    

    现在我想从内部更改它 std::map<int, double> 只是一个 std::set<int>

    所以 double d insert 函数现在将被忽略。下面的代码应该仍然有效,其中 it->second 将永远是 0.0

    Foo foo;
    for(Foo::const_iterator it = foo.begin(); it != foo.end(); ++it) {
      std::cout << it->first << " " << it->second << std::endl;
    }
    

    我怎样才能在 上课?

    Foo::const_iterator 适应新的内部环境 std::set<int>::const_iterator 老样子 std::map<int,double>::const_iterator ?

    更新: 我想摆脱 地图 是内存效率。我有几百万 实例,无法存储 double

    5 回复  |  直到 13 年前
        1
  •  2
  •   Flexo - Save the data dump sunny moon    13 年前

    会使用

    std::set<std::pair<int, double> >
    

    不足以进行这种可比性?

    如果失败,则始终可以编写自己的迭代器,该迭代器包装std::list迭代器并提供 first second

    更新,稍微做作的示例,可能会根据您的场景工作:

    #include <iostream>
    #include <set>
    
    class Foo {
      typedef std::set<int> Container;
      typedef Container::const_iterator legacy_iterator;
      Container c_;
    
      // legacy iterator doesn't have a virtual destructor (probably?), shouldn't
      // be a problem for sane usage though
      class compat_iterator : public legacy_iterator {
      public:
         compat_iterator(const legacy_iterator& it) : legacy_iterator(it) {
         }
    
         const std::pair<int,double> *operator->() const {
            static std::pair<int,double> value;
            value = std::make_pair(**this, 0.0);
            // Not meeting the usual semantics!
            return &value;
         }
      };
     public:
      typedef compat_iterator const_iterator;
    
      const_iterator begin() const { return c_.begin(); }
      const_iterator end() const { return c_.end(); }
    
    };
    
    
    
    int main() {
    
      Foo foo;
      for(Foo::const_iterator it = foo.begin(); it != foo.end(); ++it) {
         std::cout << it->first << " " << it->second << std::endl;
      }
    
    }
    
        2
  •  1
  •   Stuart Golodetz    13 年前

    像这样的怎么样?

    #include <iostream>
    #include <map>
    #include <set>
    
    struct Funky
    {
        int first;
        static const double second;
    
        Funky(int i)
        :   first(i)
        {}
    };
    
    const double Funky::second = 0.0;
    
    bool operator<(const Funky& lhs, const Funky& rhs)
    {
        return lhs.first < rhs.first;
    }
    
    class Foo
    {
    private:
        //std::map<int,double> m_data;
        std::set<Funky> m_data;
    public:
        //typedef std::map<int,double>::const_iterator const_iterator;
        typedef std::set<Funky>::const_iterator const_iterator;
    
        const_iterator begin() const
        {
            return m_data.begin();
        }
    
        const_iterator end() const
        {
            return m_data.end();
        }
    
        void insert(int i, double d)
        {
            //m_data.insert(std::make_pair(i, d));
            m_data.insert(i);
        }
    };
    
    int main()
    {
        Foo foo;
        foo.insert(23, 9.0);
        for(Foo::const_iterator it=foo.begin(), iend=foo.end(); it!=iend; ++it)
        {
            std::cout << it->first << ' ' << it->second << '\n';
        }
        return 0;
    }
    
        3
  •  0
  •   wilhelmtell    13 年前

    operator int()(const std::pair<int, double>& p) const {
        return p.first;
    }
    

    也许在包装袋里?

        4
  •  0
  •   Luca Martini    13 年前

    fake_pair 实现的类 first second set<fake_pair> 里面 Foo .

        5
  •  0
  •   DanDan    13 年前