Sign in to follow this  

Adapting STL Algorithms to Associative Containers (std::pair Elements)

This topic is 3623 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Is there a clean way to adapt the standard STL algorithms to std::pair elements? I'm frustrated with not being able to use common algorithms with associative containers like std::map. For example, let's say I have a map of some class A with a method I want to call on each.
class A // Just some class.
{
    void foo() {} // Member function I want to call with std::for_each().
};
std::map<int, A> con;
//...
std::for_each(con.begin(), con.end(), std::mem_fun_ref(A::foo)); // Won't work! The container contains std::pair<int, A> elements, not A elements!
So, is there a way around this problem? Obviously, std::for_each() isn't the only algorithm that doesn't work well with associative containers. Some offer member function versions, but the selection there is extremely limited. Thanks!

Share this post


Link to post
Share on other sites
Most(if not all) of the algorithms take a function as a last parameter so that you can access elements no matter how they are stored.(That way you can store pointers in a container and still find it useful)
as in:
int equator(pair<int,a> first, pair<int,a> second)
{
return first.fst == second.fst
}
find(vector.begin,vector.end,equator);

(I just made that up off the top of my head so it more than likely won't compile.)

Share this post


Link to post
Share on other sites
Ah, thanks, ChaosEngine! That's exactly what I was just trying to do but I didn't get the syntax right!

Also, thanks for the function-based examples; I tend to forget that the algorithms usually just take functors or function pointers, so you can pretty much do anything you need.

Share this post


Link to post
Share on other sites
SGI STL contains select1nd and select2nd as a non-standard extension. They shouldn't be too hard to implement manually:


template <typename Pair>
struct select1st : std::unary_function<typename Pair::first_type, Pair>
{
result_type& operator ()(Pair& pair)
{
return pair.first;
}
const result_type& operator ()(const Pair& pair)
{
return pair.first;
}
}
template <typename Pair>
struct select2nd : std::unary_function<typename Pair::second_type, Pair>
{
result_type& operator ()(Pair& pair)
{
return pair.second;
}
const result_type& operator ()(const Pair& pair)
{
return pair.second;
}
}



It shouldn't be too difficult to generalize that for arbitrary boost/tr1/std::tuples, either.

Share this post


Link to post
Share on other sites
TR1 does specify the template free function get_element, which gets an indexed element from a tuple and is also specialised to get an element from a std::pair, i.e. get_element< 0 >(pair);

Σnigma

Share this post


Link to post
Share on other sites

This topic is 3623 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this