Problem with VC STL vector

Problem with VC STL vector

Post by bobtabulou » Thu, 28 Jul 2005 01:06:47


Hi all,

I've been fooling around with this problem for quite a while now, I
have been reading up on functors etc., but I just can't get my head
round it. I would appreciate any guidance. Example code below:

// some class called frame

class frame {
// stuff
}

// fragment class holds a pointer to a frame obj

class fragment {
fragment(frame* fr) : _frame(fr) {}
frame* getFrame() const {return _frame;}
private:
frame* _frame;
}


// Now i store the fragments in an STL vector e.g.

typedef std::vector<fragment*> fragmentvector;
typedef fragmentvector::iterator fragmentiterator;

fragmentvector fragment_buffer;

frame* frame1 = new frame();
frame* frame2 = new frame();
frame* frame3 = new frame();

fragment* fragment1 = new fragment(frame1);
fragment* fragment2 = new fragment(frame2);
fragment* fragment3 = new fragment(frame3);

fragment_buffer.push_back(fragment1);
fragment_buffer.push_back(fragment2);
fragment_buffer.push_back(fragment3);

// ok so now 3 fragments in the buffer

// now I want to remove any fragment that has its _frame data member
// equal to "frame2" above. It is important that this data member is
// accessed through the "getFrame()" method.

// here is what I have tried:

// First create a functor to determine if a particular
// fragment has the correct value

class frameTest: public binary_function<fragmentiterator&, frame*,
bool> {
public:
frameTest(first_argument_type it) : _iter(it) {}
result_type operator()(second_argument_type pFrame);
private:
first_argument_type _iter;
};

frameTest::result_type
frameTest::operator()(frameTest::second_argument_type pFrame) {
if ((*_iter)->getFrame() == pFrame) return true;
else return false;
} // operator

// to remove any fragment from fragment_buffer where _frame == frame2 :

fragmentiterator localIterator = fragment_buffer.begin();
std::remove_if(fragment_buffer.begin(), fragment_buffer.end(),
frameTest(localIterator)(frame2));

============== end ==============

However, this returns the following error:

c:\program files\microsoft visual studio\vc98\include\algorithm(50) :
error C2064: term does not evaluate to a function
c:\program files\microsoft visual
studio\vc98\include\algorithm(299) : see reference to function template
instantiation 'class fragment **__cdecl std::find_if(class fragment **
,class fragment ** ,bool) ' being compiled

c:\program files\microsoft visual studio\vc98\include\algorithm(316) :
error C2064: term does not evaluate to a function
c:\program files\microsoft visual
studio\vc98\include\algorithm(304) : see reference to function template
instantiation 'class fragment **__cdecl std::remove_copy_if(class
fragment ** ,class fragment ** ,class fragment ** ,bool) ' being comp
iled

I have tried to look up error messages without much joy. Any help would
be appreciated.

Thanks.
 
 
 

Problem with VC STL vector

Post by Peter Koch » Thu, 28 Jul 2005 02:38:56

< XXXX@XXXXX.COM > skrev i en meddelelse
news: XXXX@XXXXX.COM ...

Ok.

Ok. But do you know who "owns" a given frame pointer? Who deletes a frame
when it is no longer in use?
No you do not. You store pointers to fragments.


Your binary comparator should compare to fragment*.

That is not enough. remove_if does not really remove the frames - it only
moves them to the end. You need to use:
fragment_buffer.erase(remove_if(begin,end,crit),end);


My best suggestion to you is not to use pointers if you can avoid them. So
far I've seen nothing here that indicates they are needed.
/Peter



 
 
 

Problem with VC STL vector

Post by emhhbmdsc » Thu, 28 Jul 2005 10:03:02

i,

I hope following code may help you.

class frame {
// stuff
};

class fragment {
public:
fragment(frame* fr) : _frame(fr) {}
frame* getFrame() const {return _frame;}
private:
frame* _frame;
};


typedef std::vector<fragment*> fragmentvector;
typedef fragmentvector::iterator fragmentiterator;

//begin zlr
/*
class frameTest: public binary_function<fragmentiterator&, frame*,
bool> {
public:
frameTest(first_argument_type it) : _iter(it) {}
result_type operator()(second_argument_type pFrame);
private:
first_argument_type _iter;
};

frameTest::result_type
frameTest::operator()(frameTest::second_argument_type pFrame) {
if ((*_iter)->getFrame() == pFrame) return true;
else return false;
} // operator
*/
class frameTest : public unary_function<fragment*,bool>{
public:
frameTest(fragmentiterator it) : _iter(it) {};

public:
bool operator()(fragment* pFragment){
return (*_iter)->getFrame() == pFragment->getFrame();

} // operator;
private:
fragmentiterator _iter;
};
//end zlr

void CTestDlg::OnBnClickedButton1()
{
// Now i store the fragments in an STL vector e.g.


fragmentvector fragment_buffer;

frame* frame1 = new frame();
frame* frame2 = new frame();
frame* frame3 = new frame();

fragment* fragment1 = new fragment(frame1);
fragment* fragment2 = new fragment(frame2);
fragment* fragment3 = new fragment(frame3);

fragment_buffer.push_back(fragment1);
fragment_buffer.push_back(fragment2);
fragment_buffer.push_back(fragment3);

fragmentiterator localIterator = fragment_buffer.begin();
//begin zlr
// std::remove_if(fragment_buffer.begin(), fragment_buffer.end(),
// frameTest(localIterator)(frame2));

fragmentiterator new_end = std::remove_if(fragment_buffer.begin(),
fragment_buffer.end(),frameTest(localIterator));

//really remove the items form vector
fragment_buffer.erase (new_end, fragment_buffer.end( ) );
//end zlr
}

Best Regards.

" XXXX@XXXXX.COM " wrote:

 
 
 

Problem with VC STL vector

Post by bob » Thu, 28 Jul 2005 17:25:37

Hi

You are of course correct; I am storing pointers to frame. The frame
objects are deleted elsewhere.

I have no idea what a binary comparator is :( apprently neither does
google :((

I am aware that remove_if doesn't really remove objs from the vector,
thanks again for the advice.

many thanks.
 
 
 

Problem with VC STL vector

Post by bob » Thu, 28 Jul 2005 17:28:39

Hi

Thanks for the advice. I have tried the code provided and it compiles
correctly. The problem is, however, that I want to pass a frame into
the remove_if function not a fragment. The idea is to remove any
fragment that has a pointer to that frame. Is what I am attempting even
possible?

Thanks again.
 
 
 

Problem with VC STL vector

Post by Hendrik Sc » Thu, 28 Jul 2005 18:21:38


A binary comparator is a function-like thingy
(either a function pointer or a function object)
that compares two objects and returns a boolean
result.
For example, this is a binary comparator that
returns 'true' if the left object is less than
the right one:

struct my_less {
bool operator()(const my& lhs, const my& rhs)
{
return lhs.get_key() < rhs.get_key();
}
};

HTH,

Schobi

--
XXXX@XXXXX.COM is never read
I'm Schobi at suespammers dot org

"Coming back to where you started is not the same as never leaving"
Terry Pratchett
 
 
 

Problem with VC STL vector

Post by emhhbmdsc » Thu, 28 Jul 2005 22:52:02

Hi,

Can you try following code?
I have add one more frame3 into the vector.
fragment* fragment4 = new fragment(frame3);//note it is frame3
fragment_buffer.push_back(fragment4);
and remove 2 framements (framement3 and 4) from the vector because they
point to the same frame3.
fragmentiterator new_end = std::remove_if(
fragment_buffer.begin(),
fragment_buffer.end(),
frameTest(frame3));//note I pass frame3 into the frameTest

//source code
class frame {
// stuff
};

class fragment {
public:
fragment(frame* fr) : _frame(fr) {}
frame* getFrame() const {return _frame;}
private:
frame* _frame;
};


typedef std::vector<fragment*> fragmentvector;
typedef fragmentvector::iterator fragmentiterator;

//begin zlr
/*
class frameTest: public binary_function<fragmentiterator&, frame*,
bool> {
public:
frameTest(first_argument_type it) : _iter(it) {}
result_type operator()(second_argument_type pFrame);
private:
first_argument_type _iter;
};

frameTest::result_type
frameTest::operator()(frameTest::second_argument_type pFrame) {
if ((*_iter)->getFrame() == pFrame) return true;
else return false;
} // operator
*/
class frameTest : public unary_function<fragment*,bool>{
public:
frameTest(frame* pFrame) : _pFrame(pFrame) {};

public:
result_type operator()(argument_type pFragment){
return _pFrame == pFragment->getFrame();

} // operator;
private:
frame* _pFrame;
};
//end zlr

void CTestDlg::OnBnClickedButton1()
{
// Now i store the fragments in an STL vector e.g.


fragmentvector fragment_buffer;

frame* frame1 = new frame();
frame* frame2 = new frame();
frame* frame3 = new frame();

fragment* fragment1 = new fragment(frame1);
fragment* fragment2 = new fragment(frame2);
fragment* fragment3 = new fragment(frame3);
fragment* fragment4 = new fragment(frame3); //note it is frame3

fragment_buffer.push_back(fragment1);
fragment_buffer.push_back(fragment2);
fragment_buffer.push_back(fragment3);
fragment_buffer.push_back(fragment4);

fragmentiterator localIterator = fragment_buffer.begin();
//begin zlr
// std::remove_if(fragment_buffer.begin(), fragment_buffer.end(),
// frameTest(localIterator)(frame2));

fragmentiterator new_end = std::remove_if(
fragment_buffer.begin(),
fragment_buffer.end(),
frameTest(frame3));));//note I pass frame3 into the frameTest

//really remove the items form vector
fragment_buffer.erase (new_end, fragment_buffer.end( ) );
//end zlr
}

Best Regards,
Zhang liren
 
 
 

Problem with VC STL vector

Post by bob » Tue, 02 Aug 2005 23:52:31

Hi

The following solution was posted on the comp.lang.c++.moderated group.
I thought I'd post it here in case anyone else has the same problem.

Perhaps you are making the problem more difficult than it needs to be.
For
example, your functor does not need to inferit from
std::binary_function<...>. Why not try:

// Functor
class frame_ptr_eq {
public:
frame_ptr_eq(frame *frame) : _frame(frame) {}
bool operator()(fragment *rhs) {
return (_frame == rhs->getFrame());
}
private:
frame *_frame;



};


// Set up frame, fragments and vector

// Use functor to remove fragments with frames equal to frame2
std::remove_if(fragment_bufferbegin(), fragment_buffer.end(),
frame_ptr_eq(frame2));