From: Pablo Aguilar (pablo.aguilar_at_[hidden])
Date: 2005-03-08 18:13:33


"Michael Goldshteyn" <mgoldshteyn_at_[hidden]> wrote in message
news:d0l8qu$qfq$1_at_sea.gmane.org...
> Given:
>
> // Definitions
>
> class Element
> {
> public:
> const std::string &GetTag() const;
> };
>
> typedef std::vector<Element> ElementContainer;
>
> // Now here is what is required
>
> ElementContainer elements;
> ...
> ElementContainer matchingElements;
> std::string matchingTag("abc");
>
> copy_if(elements.begin(),elements.end(),back_inserter(matchingElements)),pred);
>
> --
>
> What is pred? Assuming that iElements represents the iterator inside
> copy_if, pred should be something like: iElements->GetTag()==matchingTag
>
> I could go about this by creating a new function object class/struct,
> which takes matchingTag as its sole constructor argument and does the
> comparison inside operator(). But, I want to use in place composition
> using binders, etc... to create the pred, so as not to have to create a
> function object class/struct. The question is, "What piece of code should
> pred be?"
>
> // Almost does the right thing, but it's only *iElements==matchingTag, I
> need iElements->GetTag()==matchingTag
> bind_2nd(equal_to,matchingTag)
>
> This seems like a very common operation. How can I compose the predicate,
> in place to do this? If there are multiple solutions, I would like to hear
> them as well!
>
> Thanks,
>
> Michael

The first way that comes to mind:

copy_if(
      elements.begin()
    , elements.end()
    , back_inserter(matchingElements)
    , boost::bind<bool>(
          equal_to<string>()
        , boost::bind<string>(
              boost::mem_fn(&Element::GetTag)
            , _1
        )
        , matchingTag
    )
);

Note that I use the boost::bind<return_type> form, 'cuz I'm used to working
with VC6 which can't deduce template arguments correctly.

HTH

Pablo Aguilar