For Programmers: Free Programming Magazines  


Home > Archive > VC STL > August 2005 > Problem with VC STL vector









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author Problem with VC STL vector
bobtabulous@yahoo.co.uk

2005-07-26, 5:05 pm

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.

Peter Koch Larsen

2005-07-26, 5:05 pm


<bobtabulous@yahoo.co.uk> skrev i en meddelelse
news:1122394007.421054.28750@o13g2000cwo.googlegroups.com...
> 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
> }


Ok.
>
> // fragment class holds a pointer to a frame obj
>
> class fragment {
> fragment(frame* fr) : _frame(fr) {}
> frame* getFrame() const {return _frame;}
> private:
> frame* _frame;
> }


Ok. But do you know who "owns" a given frame pointer? Who deletes a frame
when it is no longer in use?
>
>
> // Now i store the fragments in an STL vector e.g.
>
> typedef std::vector<fragment*> fragmentvector;

No you do not. You store pointers to fragments.

> 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;
> };


Your binary comparator should compare to fragment*.
>
> 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));


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);

>
> ============== 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.


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.
>
> Thanks.
>

/Peter


zhanglr

2005-07-26, 10:05 pm

Hi,

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.

"bobtabulous@yahoo.co.uk" wrote:

> 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.
>
>

bob

2005-07-27, 4:05 am

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.

bob

2005-07-27, 4:05 am

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.

Hendrik Schober

2005-07-27, 4:05 am

bob <bobtabulous@yahoo.co.uk> wrote:
> [...]
> I have no idea what a binary comparator is :( apprently neither does
> google :((
> [...]


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

--
SpamTrap@gmx.de 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


zhanglr

2005-07-27, 9:06 am

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

"bob" wrote:

> 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.
>
>

bob

2005-08-02, 9:16 am

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 =3D=3D 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_buffer=AD.begin(), fragment_buffer.end(),
frame_ptr_eq(frame2));

Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com