Re: binary_function and bind1st

From: Siemel Naran (namespace_at_excite.com)
Date: 05/20/04


Date: 19 May 2004 22:48:29 -0700

greg.lilley@dcjs.virginia.gov (Greg Lilley) wrote in message

> I have an application where I want to remove all of the items that are
> in one vector from a second vector. In the following short program, my
> objective is to remove all of ourCards from cardsAvailable without
> writing a loop.

 
> struct removeCard : public std::binary_function<vector<int>,int,void>

The first_argument_type is not vector<int> but rather vector<int>&.

> {
> void
> operator() (vector<int> & cardsAvailable, int cardToRemove )const
> {
> vector<int>::iterator iter;
> iter = lower_bound(cardsAvailable.begin(),cardsAvailable.end(),
> cardToRemove);
>
> if ( iter != cardsAvailable.end()) cardsAvailable.erase(iter);
> }
> };

> for_each( ourCards.begin(), ourCards.end(), // range
> bind1st(removeCard(),cardsAvailable) ); // operation

After changing the first_argument_type as above, I believe you'll run
into the reference to reference problem. There may be a fix to the
ANSI standard to fix this by making a reference to a reference be a
reference.

Please be aware that bind1st creates a copy of cardsAvailable, and it
is this copy that changes. The simple fix is to use pointers. It
should also fix your original problem.

         for_each( ourCards.begin(), ourCards.end(), // range
                   bind1st(removeCard(),&cardsAvailable) ); // operation

> struct removeCard : public std::binary_function<vector<int>,int,void>

should be changed to

  struct removeCard : public
std::binary_function<vector<int>*,int,void>

Change operator() as appropriate.

An alternative design is to make removeCard store a reference (or
pointer) to cardsAvailable. It would have a constructor

explicit removeCard::removeCard(std::vector<int>&);

In this design you don't need binders.

> iter = lower_bound(cardsAvailable.begin(),cardsAvailable.end(),
> cardToRemove);

As a minor optimization, if ourCards is sorted, then instead of
cardsAvailable.begin() you could use the previous value of iter.
Example: for 10, 20; once you find card 10 in cardsAvailable, to find
card 20 you need only start searching cardsAvailable from card 10, not
from the beginning. Don't know how you would do this with binders
though.

Have you considered using set functions like set_difference? As far
as I know, they do employ extra storage. In other words, in

set_difference(a.begin(), a.end(), b.begin(), b.end(), c.begin());

'c' must be different from 'a'. Normally one might use
std::back_inserter(c).

Have you thought about exception safety? What if you are to remove 2
cards 10 and 20 and you removed 10 and removing 20 throws an
exception. What then? It is not necessary to fix this scenario right
now, but at least be aware of it.

Finally, removing an element from a vector is an O(N) operation, but
removing from a list is O(1).



Relevant Pages

  • device error code 12:
    ... I am trying to fix a problem on a Dell Inspiron 5000e with SP2. ... when swapping that card for a Netgear WG511wireless card, ...
    (microsoft.public.windowsxp.help_and_support)
  • [GIT PULL] FireWire update
    ... to receive the following fix for a regression since 2.6.24-rc1. ... firewire: fw-sbp2: fix refcounting ... to] reschedule itself because it failed due to the bus reset, ... and hence sbp2_updatewould take an additional reference. ...
    (Linux-Kernel)
  • Re: [PATCH] tcp: splice as many packets as possible at once
    ... adding with this bug fix. ... The trick in socket splicing where we try to convert the skb->data ... The idea is to pass the virt_to_pagereference via the pipe ... and refcount the buffer using a SKB reference. ...
    (Linux-Kernel)
  • Re: [PATCH] tcp: splice as many packets as possible at once
    ... adding with this bug fix. ... The trick in socket splicing where we try to convert the skb->data ... The idea is to pass the virt_to_pagereference via the pipe ... unsigned int len, unsigned int offset, ...
    (Linux-Kernel)
  • Re: Function isnt available in expressions in Query expression
    ... "ruth" wrote in message ... > I was able to fix this problem by changing the code. ... The way I fixed it was to always remove the reference and add it ... Dim loRef As Access.Reference ...
    (microsoft.public.access.modulesdaovba)