D
Denis Remezov
[snip]Greg said: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.
I have tried a number of different variations using the for_each
algorithm without success, and am currently getting a C2664 error that
the compiler cannot convert parameter 1. I am new to STL and not all
that adept with C++ either, so I'm sure there is something basic that
I am missing. Anyway, I have created the following short program to
demonstrate my problem. Any assistance will be greatly appreciated.
// Remove Card test using STL
#include <iostream> // for cout
#include <vector> // for vector
#include <algorithm> // for lower_bound, for_each
#include <functional> // for binary_function
using namespace std;
//STL support functions or objects
struct removeCard : public std::binary_function<vector<int>,int,void>
{
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);
}
};
// To display contents of a container - For testing only
void print ( int element )
{
cout << element << ' ';
}
int main()
{
vector<int> ourCards;
// add two cards to ourCards vector
ourCards.push_back(10);
ourCards.push_back(20);
vector<int> cardsAvailable;
vector<int>::iterator iter;
// initialize cardsAvailable with all 52 cards
for ( int i = 0; i < 52; ++i) cardsAvailable.push_back(i);
// remove all of our cards from the deck
for_each( ourCards.begin(), ourCards.end(), // range
bind1st(removeCard(),cardsAvailable) ); // operation
// display all of the remaining cards in the deck
for_each( cardsAvailable.begin(), cardsAvailable.end(), print );
return 0;
}
As Victor said, you can't use a non-const reference with bind1st.
You could do otherwise, but as a dirty cheap fix (I'm curious if anyone
thinks it's a stylistic kludge) I'd change to binding a pointer to a vector:
struct removeCard : public std::binary_function<vector<int>*, int, void> {
void operator() (vector<int>* p_cardsAvailable, int cardToRemove) const {
vector<int>::iterator iter;
iter = lower_bound(p_cardsAvailable->begin(), p_cardsAvailable->end(),
cardToRemove);
if ( iter != p_cardsAvailable->end()) p_cardsAvailable->erase(iter);
}
};
.... and the usage in main() is:
for_each( ourCards.begin(), ourCards.end(), // range
bind1st(removeCard(), &cardsAvailable) ); // operation
Denis