Why overload the function call operator ( )?

Why? I am very confused, can someone please help?
... because when you do that, your class (or struct) becomes a functor.
Functors are commonly used with the function templates from the algorithm library.

You are however encouraged to use lambda functions instead of functors if your C++ compiler supports them.

http://cplusplus.com/reference/algorithm/generate/

1
2
3
4
5
6
7
8
9
10
11
// ...

struct c_unique {
  int current;
  c_unique() {current=0;}
  int operator()() {return ++current;}
} UniqueNumber;

// ...

std::generate (myvector.begin(), myvector.end(), UniqueNumber);


Edit:
http://stackoverflow.com/questions/356950/c-functors-and-their-uses
Last edited on
But why? Is there any use in them that cannot be done otherwise?

I know what it does except what use is it?
So its faster easier then function pointers and it can contain state? Makes sense now thanks :D
I am still confused though on why it is better then using a function pointer...

Still very confused lol.
You already did mention the state. IIRC, there could be different optimization possibilities for the compiler too.
Last edited on
But cant it be done with a normal class? Just add a function to it, whats so good about using a functor?
The good thing about providing a function call operator rather than some other named member function is that
a) the calling code doesn't need to know which function to call (imagine how much more awkward it would be to sort a vector, for example, if you had to provide both the comparison object and a member function pointer to call in it)
b) it works exactly the same way whether a function, a function pointer, a lambda expression, a bind expression, or a hand-written functor is used. In short, it's simple.
Last edited on
What do you mean vector?

I know it works the same way except it can be done with a normal member function...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
template <class RandomAccessIterator, class Compare>
void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp);

bool ccw(const point &a, const point &b);
class near{
private:
   point center;
public:
   near(const point &center): center(center){}
   bool operator()(const point &a, const point &b);
};

class yx{
public:
   bool less(const point &a, const point &b);
};

sort(v.begin(), v.end(), ccw);
sort( v.begin(), v.end(), near(point(0,0)) );
sort( v.begin(), v.end(), yx() ); //¿? 


`std::sort' decided to use `comp(a,b)' to compare elements.
It could have used `comp.less(a,b)' instead, but then it would not work with functions.
Last edited on
What? Can you write a program I can execute and examine please?
Sure, here's something to sink your teeth into, along the same vein ne555 was going, but with strings instead of points and using std::sort/std::generate. You will find a few overloaded operator() within.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <random>
#include <functional>
#include <sstream>


std::ostream& operator<<(std::ostream& os, const std::vector<std::string>& v)
{
    os << " -----\n" ;
    for ( auto& s : v )
        os << s << '\n' ;

    return os << " -----\n" ;
}

class StringGenerator
{
public:
    StringGenerator() : _engine(std::random_device()()), _dist('a', 'z') {}

    std::string operator()()
    {
        std::ostringstream result ;
        for ( unsigned i=0; i<4; ++i )
        {
            result << static_cast<char>(_dist(_engine)) ;
        }

        result << " (" << _stringNumber++ << ")" ;

        return result.str() ;
    }

private:
    std::mt19937 _engine ;
    std::uniform_int_distribution<unsigned> _dist ;

    static unsigned _stringNumber ;
};

unsigned StringGenerator::_stringNumber = 1 ;


struct descending 
{
    bool operator()(const std::string& a, const std::string& b) const
    {                                                          
        return a > b ;
    }
};

struct byNum
{
    bool operator()(const std::string& a, const std::string& b) const
    {                                                            
        unsigned aNum, bNum ;
        char dummy ;
        std::istringstream(a.substr(a.find('(')+1)+ b.substr(b.find('(')+1)) 
            >> aNum >> dummy >> bNum ;
        return aNum < bNum ;
    }
};

void ignoreLine(std::istream& is)
{
    is.ignore(std::numeric_limits<std::streamsize>::max(), '\n') ;
}

int main()
{
    StringGenerator gen ;
    std::vector<std::string> strings(25) ;
    std::generate(strings.begin(), strings.end(), StringGenerator()) ;

    std::cout << "Sorted in ascending order\n" ;
    std::sort(strings.begin(), strings.end()) ;
    std::cout << strings ;
    ignoreLine(std::cin) ;

    std::cout << "Sorted in descending order\n" ;
    std::sort(strings.begin(), strings.end(), descending()) ;
    std::cout << strings ;
    ignoreLine(std::cin) ;

    std::cout << "Sorted according to parenthetic value\n" ;
    std::sort(strings.begin(), strings.end(), byNum()) ;
    std::cout << strings ;
    ignoreLine(std::cin) ;
}
What is a vector? And damn thats complex
How do you get to overloaded operators but haven't covered vectors at all? =/

A vector is basically the std:: library version of a dynamic array, and it's not terribly complex after you've had a little experience using std:: containers/algorithms.
idk lol.

Neither have I gone through containers or algorithms. lol

Should I just save this code for now and either pm you or make a new thread explaining any further confusion?
> How do you get to overloaded operators but haven't covered vectors at all?
Functions -> Overloading functions -> Templates.
Operators are functions with a special signature.

¿what do you need to know vector for?

@OP: http://cplusplus.com/reference/
Should I just save this code for now and either pm you or make a new thread explaining any further confusion?


Overloaded operator() gets most of its use through interfacing with library-ish code. Maybe just note for the moment that it is a way to make an object behave like a function. It will become more useful, the more you know.
Ok thanks
Topic archived. No new replies allowed.