Use of for_each on map elements

前端 未结 11 729
北荒
北荒 2021-01-30 10:29

I have a map where I\'d like to perform a call on every data type object member function. I yet know how to do this on any sequence but, is it possible to do it on an associativ

相关标签:
11条回答
  • 2021-01-30 10:54

    For fellow programmers who stumble upon this question from google, there is a good way using boost.

    Explained here : Is it possible to use boost::foreach with std::map?

    Real example for your convenience :

    // 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;
    }
    

    enjoy.

    0 讨论(0)
  • 2021-01-30 11:03

    Will it work for you ?

    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));
    
    0 讨论(0)
  • 2021-01-30 11:04

    From what I remembered, C++ map can return you an iterator of keys using map.begin(), you can use that iterator to loop over all the keys until it reach map.end(), and get the corresponding value: C++ map

    0 讨论(0)
  • 2021-01-30 11:05

    I wrote this awhile back to do just what you're looking for.

    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;
        };
    }
    
    0 讨论(0)
  • 2021-01-30 11:09

    It's unfortunate that you don't have Boost however if your STL implementation has the extensions then you can compose mem_fun_ref and select2nd to create a single functor suitable for use with for_each. The code would look something like this:

    #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>()));
    }
    

    Note that if you don't have access to compose1 (or the unary_compose template) and select2nd, they are fairly easy to write.

    0 讨论(0)
  • 2021-01-30 11:12

    C++11 allows you to do:

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

    C++17 allows you to do:

    for (const auto& [key, value] : myMap) {
        std::cout << key << " has value " << value << std::endl;
    }
    

    using structured binding.

    UPDATE:

    const auto is safer if you don't want to modify the map.

    0 讨论(0)
提交回复
热议问题