?
Solved

use of function objects

Posted on 2002-06-24
15
Medium Priority
?
213 Views
Last Modified: 2010-04-01
When is it desirable to write a class that overloads operator() instead of using a function?  C
0
Comment
Question by:nke2000
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 2
  • 2
  • +7
15 Comments
 
LVL 3

Expert Comment

by:Crius
ID: 7105086
When you want to be able to do something like:

   MyObject num1, num2, num3;

   (do stuff with them)

   num3 = num1 + num2;

instead of:
   MyObject num1, num2, num3;

   (do stuff with them)

   num3.SetValue(num1);
   num3.AddValue(num2);
0
 

Author Comment

by:nke2000
ID: 7105111
Crius,
I may be misunderstanding your point, but that looks like an overload of operator+, not of operator().  I don't see how nums1-3 are used as function objects.
0
 
LVL 3

Expert Comment

by:Crius
ID: 7105173
Sorry, my mistake. When you said operator(), I though you were referring to operator overloads in general, and didn't specify whether it was operator+, operator=, etc.

From what little I know of operator(), I have only seen it used in templates, but I don't know why or how. Sorry.
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 3

Expert Comment

by:jtm111
ID: 7105177
sometimes people want to mimic fortran-style matrix indexes so they might overload () as in:

element(1,3) = 12.0

that's the typical use for me anyway.
0
 
LVL 30

Accepted Solution

by:
Axter earned 400 total points
ID: 7105448
There are times when you want to pass a function, that can temporaraly store information while been iterated by another object.  A regular function can't do this adaquately.

Example:
class TestOp
{
public:
     TestOp(int x) : m_x(x){}
     void operator()(int y)
     {
          cout << m_x << " * " << y << " = " << m_x * y << endl;
          ++m_x;
     }
     int m_x;
};

int main(int argc, char* argv[])
{
     int IntArr[5] = {1, 10, 20, 100, 1000};
     for_each(&IntArr[0], &IntArr[5], TestOp(7));

     system("pause");
     return 0;
}
0
 
LVL 22

Expert Comment

by:ambience
ID: 7106799
>> When is it desirable to write a class that overloads operator() instead of using a function?

i think its a matter of taste and C++ practice, ofcourse you can equivalently do such situations using global variables and functions, but functors are much more elegant and safer way to do it the C++ way.

couple functors with templates and you have some very powerful C++ language constructs that can save you a lot of time and much safer in terms of strict type-checking.

Also if you are going to use STL (re-usability) you might find the use of functors as inevitable.

Whereas going everything on your own from scratch you can avoid functors at all costs.
0
 
LVL 3

Expert Comment

by:jimbucci
ID: 7107072
Providing another example to Crius' example:

A lot of it depends on what your classes can actually do.  For example: say you have a simple string class (textbook example)
class MyString
{
   char string[20];
   MyString operator+( MyString& sString);
... (most code is missing)
}

Now you can easily concatenate strings
MyString s1,s2,s3;

s1 = s2 + s3;  
instead of using strcat().
Stroustrup "The C++ Programming Language" has a good example of a string class.

Sorry for iterating Crius' response.  I would use this operator if I had a class where the objects can be created using combination of two other objects.  But then you can be as creative as you like with these operators based on the complexity your objects.
Also, use of operators makes for cleaner looking code.
0
 
LVL 3

Expert Comment

by:Crius
ID: 7107777
Thanks jimbucci, but Crius answered the wrong question. :) nke2000 was talking about one particular operator overload, the () one.
0
 
LVL 3

Expert Comment

by:jimbucci
ID: 7107836
I stand corrected.  The examples provided clearly show some uses.  I've never overloaded operator(), but I can now see its uses.
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 7109368
Basically it lets you use the name of the object as if it were a function name.  For instance, let's say you have an class named MathOp.  You instantiate two objects of that class:

CMathOp cAdd("+");
CMathOp cSubtract("-");

and later you could use:

    cAdd(1,2);
or
    cSubract(7,3);

Instead of the clumsier:

    cAdd.DoYourOperation(1,2);
    cSubtract.DoYourOperation(7,3);

-- Dan
0
 
LVL 9

Expert Comment

by:jasonclarke
ID: 7110545
The obvious answer is anytime you want a class to behave like a function,  the most common *required* usage is when you define class functors for stl algorithms, eg. when you implement your own sorting predicate for std::sort.

Another link with a good example is:

http://www.gotw.ca/gotw/083.htm
0
 
LVL 9

Expert Comment

by:jasonclarke
ID: 7110572
STL Class Functionoid Sort Predicate example:

#include <algorithm>
#include <vector>

using namespace std;

class X
{
public:

    int val;
};

class XSortPredicate
{
public:
    bool operator()(const X& lhs, const X& rhs)
    {
        return lhs.val < rhs.val;
    }
};

void f()
{
    std::vector<X> xvec;
    std::sort(xvec.begin(), xvec.end(), XSortPredicate());
}

BTW, there are significant advantages to using this method of defining predicates than using a function pointer... efficiency being a notable one... the compiler could inline the function object, hence potentially removing *all* function calls from the sort algorithm (hence why std::sort is potentially much more efficient than qsort).
0
 

Author Comment

by:nke2000
ID: 7111388
thanks everyone for your help.  Axter's answer is almost identical to Stroustrup.  I was able to step through his code to get a better handle on the problem.
0
 
LVL 1

Expert Comment

by:ramshakal
ID: 7111462
>When is it desirable to write a class that overloads operator() instead of using a function

Generally you will find operator() in most of the interfaces of kind Sequence or Iterators.  And its good design pratice to use this operator for interfaces of these kind because it allows internal details hidden from users and thus presenting simplified view of Interface.

Once you design more and more classes and follow  design approach of " outside first (interfaces first) and then  inside (data ). You will automatically find the need of this operator.  You already know how to use this. So here I am giving you a probelm where its desirable to use this operator to simplify things.

class LinkedListIterator;
class LinkedList;
 
 class Node {
   // No public members; this is a "private class"
   friend LinkedListIterator;   // A friend class
   friend LinkedList;
   Node* next_;
   int elem_;
 };
 
 class LinkedListIterator {
 public:
   bool operator== (LinkedListIterator i) const;
   bool operator!= (LinkedListIterator i) const;
   void operator++ ();   // Go to the next element
   int& operator*  ();   // Access the current element
 private:
   LinkedListIterator(Node* p);
   Node* p_;
   friend LinkedList;  // so LinkedList can construct a LinkedListIterator
 };
 
 class LinkedList {
 public:
   void append(int elem);    // Adds elem after the end
   void prepend(int elem);   // Adds elem before the beginning
   // ...
   LinkedListIterator begin();
   LinkedListIterator end();
   // ...
 private:
   Node* first_;
 };

inline void LinkedListIterator::operator++()
 {
   assert(p_ != NULL);  // or if (p_==NULL) throw ...
   p_ = p_->next_;
 }
 
 inline int& LinkedListIterator::operator*()
 {
   assert(p_ != NULL);  // or if (p_==NULL) throw ...
   return p_->elem_;
 }


The key insight is the realization that a LinkedList is not a chain of Nodes. That may be how it is built, but that is not what it is. What it is is a sequence of elements. Therefore the LinkedList abstraction should provide a "LinkedListIterator" class as well, and that "LinkedListIterator" might have an operator++ to go to the next element and operator () to access elements Node Value.

Thanks,
RSV
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Templates For Beginners Or How To Encourage The Compiler To Work For You Introduction This tutorial is targeted at the reader who is, perhaps, familiar with the basics of C++ but would prefer a little slower introduction to the more ad…
IntroductionThis article is the second in a three part article series on the Visual Studio 2008 Debugger.  It provides tips in setting and using breakpoints. If not familiar with this debugger, you can find a basic introduction in the EE article loc…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.
Suggested Courses

777 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question