代码之家  ›  专栏  ›  技术社区  ›  Antonio Pérez

每个地图元素的用法

  •  37
  • Antonio Pérez  · 技术社区  · 14 年前

    我有一个映射,我想在其中对每个数据类型对象成员函数执行调用。我还知道如何在任何序列上执行此操作,但是,是否可以在关联容器上执行此操作?

    我能找到的最接近的答案是: Boost.Bind to access std::map elements in std::for_each . 但是我不能在我的项目中使用boost,所以,是否有一个stl替代方法我缺少boost::bind?

    如果不可能,我想为指向数据对象的指针创建一个临时序列,然后调用它上的每个指针,如下所示:

    class MyClass
    {
    public:
     void Method() const;
    }
    
    std::map<int, MyClass> Map;
    //...
    
    std::vector<MyClass*> Vector;
    std::transform(Map.begin(), Map.end(), std::back_inserter(Vector), std::mem_fun_ref(&std::map<int, MyClass>::value_type::second));
    std::for_each(Vector.begin(), Vector.end(), std::mem_fun(&MyClass::Method));
    

    它看起来太模糊了,我不太喜欢它。有什么建议吗?

    11 回复  |  直到 6 年前
        1
  •  49
  •   Antonio Pérez    12 年前

    您可以迭代 std::map 对象。每个迭代器将指向 std::pair<const T,S> 在哪里? T S 与您在 map .

    这里是:

    for (std::map<int, MyClass>::iterator it = Map.begin(); it != Map.end(); ++it)
    {
      it->second.Method();
    }
    

    如果你还想用 std::for_each ,传递一个函数 std::pair<const int, MyClass>& 而是作为一个论点。

    例子:

    void CallMyMethod(std::pair<const int, MyClass>& pair) // could be a class static method as well
    {
      pair.second.Method();
    }
    

    并把它传递给 性病:每一个 :

    std::for_each(Map.begin(), Map.end(), CallMyMethod);
    
        2
  •  74
  •   BenC    10 年前

    C++ 11允许你这样做:

    for (const auto& kv : myMap) {
        std::cout << kv.first << " has value " << kv.second << std::endl;
    }
    

    更新:

    如果不想修改地图,const auto更安全。

        3
  •  8
  •   bobah    14 年前

    一个普通的C++怎么样?(示例根据@noah roberts的注释固定)

    for(std::map<int, MyClass>::iterator itr = Map.begin(), itr_end = Map.end(); itr != itr_end; ++itr) {
      itr->second.Method();
    }
    
        4
  •  6
  •   Christian Rapp    9 年前

    C++ 14带来了通用的lambda。 这意味着我们可以很容易地为每个用户使用std:::

    std::map<int, int> myMap{{1, 2}, {3, 4}, {5, 6}, {7, 8}};
    
    std::for_each(myMap.begin(), myMap.end(), [](const auto &myMapPair) {
        std::cout << "first " << myMapPair.first << " second "
                  << myMapPair.second << std::endl;
    });
    

    我认为std::for_each有时比基于for循环的简单范围更适合。例如,当您只想循环遍历映射的子集时。

        5
  •  3
  •   David Joyner    14 年前

    不幸的是,您没有boost,但是如果您的STL实现有扩展,那么您可以编写mem_fun_-ref并选择2nd来创建一个适合每个函数使用的函数。代码应该如下所示:

    #include <algorithm>
    #include <map>
    #include <ext/functional>   // GNU-specific extension for functor classes missing from standard STL
    
    using namespace __gnu_cxx;  // for compose1 and select2nd
    
    class MyClass
    {
    public:
        void Method() const;
    };
    
    std::map<int, MyClass> Map;
    
    int main(void)
    {
        std::for_each(Map.begin(), Map.end(), compose1(std::mem_fun_ref(&MyClass::Method), select2nd<std::map<int, MyClass>::value_type>()));
    }
    

    请注意,如果您不能访问compose1(或一元\u compose模板)并选择2nd,那么它们很容易编写。

        6
  •  2
  •   Community paulsm4    7 年前

    对于那些从谷歌偶然发现这个问题的程序员来说,使用boost有一个很好的方法。

    解释如下: Is it possible to use boost::foreach with std::map?

    方便您使用的真正示例:

    // typedef in include, given here for info : 
    typedef std::map<std::string, std::string> Wt::WEnvironment::CookieMap
    
    Wt::WEnvironment::CookieMap cookie_map = environment.cookies();
    
    BOOST_FOREACH( const Wt::WEnvironment::CookieMap::value_type &cookie, cookie_map )
    {
        std::cout << "cookie : " << cookie.first << " = " << cookie.second << endl;
    }
    

    享受。

        7
  •  0
  •   a1ex07    14 年前

    这对你有用吗?

    class MyClass;
    typedef std::pair<int,MyClass> MyPair;
    class MyClass
    {
      private:
      void foo() const{};
    public:
    static void Method(MyPair const& p) 
    {
        //......
            p.second.foo();
    };
    }; 
    // ...
    std::map<int, MyClass> Map;
    //.....
    std::for_each(Map.begin(), Map.end(), (&MyClass::Method));
    
        8
  •  0
  •   aJ.    14 年前

    举个例子:

    template <class key, class value>
    class insertIntoVec
    {
    public:
        insertIntoVec(std::vector<value>& vec_in):m_vec(vec_in)
        {}
    
        void operator () (const std::pair<key, value>& rhs)  
        {   
            m_vec.push_back(rhs.second);
        }
    
    private:
        std::vector<value>& m_vec;
    };
    
    int main()
    {
    std::map<int, std::string> aMap;
    aMap[1] = "test1";
    aMap[2] = "test2";
    aMap[3] = "test3";
    aMap[4] = "test4";
    
    std::vector<std::string> aVec;
    
    aVec.reserve(aMap.size());
    std::for_each(aMap.begin(), aMap.end(),
              insertIntoVec<int, std::string>(aVec) 
        );
    

    }

        9
  •  0
  •   vodkhang    14 年前

    从我所记得的,C++映射可以返回一个使用Map .Read()的密钥迭代器,您可以使用迭代器遍历所有键,直到它到达MAP.Enter(),并获得相应的值: C++ map

        10
  •  0
  •   moswald Jarod42    14 年前

    我写这封信是为了满足你的需求。

    namespace STLHelpers
    {
        //
        // iterator helper type for iterating through the *values* of key/value collections
        //
    
        /////////////////////////////////////////////
        template<typename _traits>
        struct _value_iterator
        {
            explicit _value_iterator(typename _traits::iterator_type _it)
                : it(_it)
            {
            }
    
            _value_iterator(const _value_iterator &_other)
                : it(_other.it)
            {
            }
    
            friend bool operator==(const _value_iterator &lhs, const _value_iterator &rhs)
            {
                return lhs.it == rhs.it;
            }
    
            friend bool operator!=(const _value_iterator &lhs, const _value_iterator &rhs)
            {
                return !(lhs == rhs);
            }
    
            _value_iterator &operator++()
            {
                ++it;
                return *this;
            }
    
            _value_iterator operator++(int)
            {
                _value_iterator t(*this);
                ++*this;
                return t;
            }
    
            typename _traits::value_type &operator->()
            {
                return **this;
            }
    
            typename _traits::value_type &operator*()
            {
                return it->second;
            }
    
            typename _traits::iterator_type it;
        };
    
        template<typename _tyMap>
        struct _map_iterator_traits
        {
            typedef typename _tyMap::iterator iterator_type;
            typedef typename _tyMap::mapped_type value_type;
        };
    
        template<typename _tyMap>
        struct _const_map_iterator_traits
        {
            typedef typename _tyMap::const_iterator iterator_type;
            typedef const typename _tyMap::mapped_type value_type;
        };
    }
    
        11
  •  0
  •   HmdRmz    6 年前

    下面是一个例子,说明如何为每个地图使用。

    std::map<int, int> map;
    
    map.insert(std::pair<int, int>(1, 2));
    map.insert(std::pair<int, int>(2, 4));
    map.insert(std::pair<int, int>(3, 6));
    
    auto f = [](std::pair<int,int> it) {std::cout << it.first + it.second << std::endl; };
    std::for_each(map.begin(), map.end(), f);