|
-
May 28th, 2010, 12:46 PM
#16
Re: Functor Tutorial
 Originally Posted by Peter_APIIT
What is the advantage of functor organization in the case of a class is derived from unary_function ?
In my opinion, functor not just "is nothing more than a wrapper to "operator<". " but normally it is designed as a predicate for looping construct.
Why you say functor is a wrapper for operator< ?
Please comment.
If you can borrow or get a copy of effective STL by Scott Meyers he does a good job of explaining why. A function pointer has to be copied by value. Using a functor can result in more effecient inline code. From my point of view as an OO programmer a functor seems more intuitive to me. Also functors are classes/structs and therefore you can inherit from other classes within the STL that makes them more adaptable. Take a look at the following example. Notice that the functor inherits from the unary_function class. This is critical if you want to be able to take advantage of things like not1. Instead of writing two functors you write one and then use not1 to make it do the opposite.
http://cplusplus.com/reference/std/functional/not1/
In my opinion a functor is a much more powerful tool then a global or static predicate function.
-
May 28th, 2010, 09:29 PM
#17
Re: Functor Tutorial
I learn a lot from this topic.
Do you know what is the specific item number for the book of effective STL ?
Thanks.
Thanks for your help.
-
May 29th, 2010, 05:20 AM
#18
Re: Functor Tutorial
Item 39. Make predicates pure functions
But to be honest, the entire book is gold. If you can get your hands on it, read all of it.
Is your question related to IO?
Read this C++ FAQ article at parashift by Marshall Cline. In particular points 1-6.
It will explain how to correctly deal with IO, how to validate input, and why you shouldn't count on "while(!in.eof())". And it always makes for excellent reading.
-
May 30th, 2010, 03:24 AM
#19
Re: Functor Tutorial
Thanks I do have a copy of the book.
Thanks for your help.
-
May 31st, 2010, 05:25 AM
#20
Re: Functor Tutorial
Quote:
My Question:
1. Is the range argument always pass to first or second argument ?
the range argument is passed as the only argument to the predicate
which expect one argument. so there is no second argument.
Does the predicate is the unary functor created by bind1st() ?
I understand that the bind1st(functor, value), value is bind to first parameter of the functor.
Quote:
bind1st()
This function constructs an unary function object from the binary function object op by binding its first parameter to the fixed value x.
AFAIK, the bind1st is convert the binary functor to unary functor with the value bind to first parameter of binary functor.
I wonder is the range argument is passes to the unary functor created by bind1st().
Thanks for your help.
Thanks for your help.
-
May 31st, 2010, 07:10 AM
#21
Re: Functor Tutorial
 Originally Posted by Peter_APIIT
Quote:
My Question:
1. Is the range argument always pass to first or second argument ?
the range argument is passed as the only argument to the predicate
which expect one argument. so there is no second argument.
Does the predicate is the unary functor created by bind1st() ?
I understand that the bind1st(functor, value), value is bind to first parameter of the functor.
Quote:
bind1st()
This function constructs an unary function object from the binary function object op by binding its first parameter to the fixed value x.
AFAIK, the bind1st is convert the binary functor to unary functor with the value bind to first parameter of binary functor.
I wonder is the range argument is passes to the unary functor created by bind1st().
Thanks for your help.
I'm afraid I don't understand your question, but I'll try to just talk about what I know and see if it helps.
There are typically two types of functors in stl algorithms:
- Unary functors:
These are used for all the remove_if etc. The argument passed to the functor is the value you want to test.
- Binary functors
These are almost always used to compare two elements. When you write pred(a, b), it means "Once ordered, is a before b".
I'm not sure what "range" to do with anything. I know of no functor that takes a range argument ( and most stl algorithms are range-unaware anyways).
bind1st and bind2nd will bind depending on your needs.
For example, if you want to remove all elements strictly smaller than 5, then you can call
Code:
std::remove_if(first, last, std::bind2nd(std::less<int>(), 5)
but if you want to remove all elements greater than 5:
Code:
std::remove_if(first, last, std::bind2nd(std::greater<int>(), 5)
OR
std::remove_if(first, last, std::bind1nd(std::less<int>(), 5)
Does that answer your question?
Is your question related to IO?
Read this C++ FAQ article at parashift by Marshall Cline. In particular points 1-6.
It will explain how to correctly deal with IO, how to validate input, and why you shouldn't count on "while(!in.eof())". And it always makes for excellent reading.
-
May 31st, 2010, 10:44 AM
#22
Re: Functor Tutorial
mistake, nm.
I'm not sure I understand peter's question, but 'the range' argument is passed to the function object (made by bind1st/bind2nd), by the algorithm (e.g. std::for_each or find_if etc.)
Last edited by Amleto; May 31st, 2010 at 10:49 AM.
-
June 1st, 2010, 11:23 AM
#23
Re: Functor Tutorial
 Originally Posted by Peter_APIIT
I learn a lot from this topic.
Do you know what is the specific item number for the book of effective STL ?
Thanks.
All of chapter 6 deals with functors. Read every item in that chapter.
-
June 1st, 2010, 12:25 PM
#24
Re: Functor Tutorial
Personally I feel that bind1st and bind2nd have both been effectively deprecated now that boost::bind has been upgraded to std::bind in C++1x. It's a much more versatile adapter.
-
June 3rd, 2010, 04:32 AM
#25
Re: Functor Tutorial
I have practice the functor concepts through exercise but i encounter error for the below code.
The below is used to check whether a particular type of folder icon exist in the vector of folderIcon class.
Code:
bool folderIcon::IsExistFolderIconType(int folderIconType)
{
return getFolderIconType() == folderIconType;
}
void folderIconFactory::createFolderIcon(int& folderIconType)
{
folderIconVecIte myIte
= find(iconPool.begin(), iconPool.end(),
std::bind1st(
std::mem_fun(&folderIcon::IsExistFolderIconType),
folderIconType) );
}
I used the predicate in another class definition which is folderIconFactory.
error C2440: 'initializing' : cannot convert from 'const int' to 'folderIcon *
If i not mistaken, i remember that we need the this pointer when creating MF functor.
Please explain what is the error ?
Thanks.
Thanks for your help.
-
June 4th, 2010, 01:44 AM
#26
Re: Functor Tutorial
Amleto has answers my question.
I made a mistake, the bind1st and bind2nd only accepts binary functor where my member function is a unary functor and the find_if.
I switch to boost now.
Code:
folderIconVecIte myIte
= find_if(iconPool.begin(), iconPool.end(),
boost::bind(
boost::mem_fn(&folderIcon::IsExistFolderIconType),
_1, folderIconType) );
Compile OK
folderIconVecIte myIte
= find_if(iconPool.begin(), iconPool.end(),
boost::bind(
boost::mem_fn(&folderIcon::IsExistFolderIconType),
_1)(folderIconType) );
Compile Error - 2
Why the second one has compile error since i follow the bind documentation ?
Solve.
Last edited by Peter_APIIT; June 4th, 2010 at 02:19 AM.
Thanks for your help.
-
June 5th, 2010, 12:46 PM
#27
Re: Functor Tutorial
 Originally Posted by Peter_APIIT
Amleto has answers my question.
I made a mistake, the bind1st and bind2nd only accepts binary functor where my member function is a unary functor and the find_if.
I switch to boost now.
Code:
folderIconVecIte myIte
= find_if(iconPool.begin(), iconPool.end(),
boost::bind(
boost::mem_fn(&folderIcon::IsExistFolderIconType),
_1, folderIconType) );
Compile OK
folderIconVecIte myIte
= find_if(iconPool.begin(), iconPool.end(),
boost::bind(
boost::mem_fn(&folderIcon::IsExistFolderIconType),
_1)(folderIconType) );
Compile Error - 2
Why the second one has compile error since i follow the bind documentation ?
Solve.
boost::bind( func, _1) , e.g., makes the functor. boost::bind( func, _1)(5) makes the functor and calls it. so the return type of boost::bind( func, _1)(5) is the same as the return type of func.
Last edited by Amleto; June 5th, 2010 at 01:33 PM.
-
June 5th, 2010, 01:02 PM
#28
Re: Functor Tutorial
 Originally Posted by Peter_APIIT
I used the predicate in another class definition which is folderIconFactory.
If i not mistaken, i remember that we need the this pointer when creating MF functor.
Please explain what is the error ?
Thanks.
might be more to do with you trying to use bind1st on a unary function.
or that std::mem_fun(&folderIcon::IsExistFolderIconType) makes a functor that takes no argument.
-
June 6th, 2010, 02:10 AM
#29
Re: Functor Tutorial
 Originally Posted by Amleto
boost::bind( func, _1) , e.g., makes the functor. boost::bind( func, _1)(5) makes the functor and calls it. so the return type of boost::bind( func, _1)(5) is the same as the return type of func.
I don't get what you mentioned here.
Thanks for your help.
-
June 6th, 2010, 05:14 AM
#30
Re: Functor Tutorial
 Originally Posted by Peter_APIIT
I don't get what you mentioned here.
assume signature:
bool function(int);
you asked why syntax like boost:bind( function, _1)(5) didnt work in find_if.
find_if needs a unary function as a predicate, and boost:bind( function, _1)(5) does not return a unary function. it makes the functor, and passes 5 to its operator().
boost:bind( function, _1)(5) is the same as function(5) which gives a bool return type.
so of course something like
std::find_if(itBegin, itEnd, bool) is not going to compile.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|