3

I have a question regarding the syntax of how to call a functor in C++. In the code below, why do the first 2 examples work whilst the 3rd and 4th attempt do not?

Also I can call ob (100); and it will output 300, but why can't I call Class(100) and have it output 300? Is there any way to use the overloaded operator () without instantiating a new object?

#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>

using namespace std; 


struct Class
{ 
    void operator() (int a) 
    { 
        cout << a * 3 << " "; 
    } 
} ob; 


int main() 
{ 

    int arr[5] = { 1, 5, 2, 4, 3 }; 

    cout << "Multiple of 3 of elements are : "; 
    for_each(arr, arr + 5, Class());
    cout << endl; 
    for_each(arr, arr + 5, ob); 
    cout << endl; 

    // Why do these not work???
    for_each(arr, arr + 5, Class);
    for_each(arr, arr + 5, ob());

}
alter_igel
  • 6,899
  • 3
  • 21
  • 40
BYS2
  • 5,199
  • 5
  • 24
  • 32

1 Answers1

7

std::for_each, like many tools in the <algorithms> library, expects something like a function to be passed. Let's look at its signature:

template< class InputIt, class UnaryFunction >
UnaryFunction for_each( InputIt first, InputIt last, UnaryFunction f );

The type UnaryFunction is expected to be something that you can pass by value f, and which you can call like a function, as in f(value);

There are a couple things that satisfy this:

  • Function pointers
  • Functor objects, which are instances of a class that overloads operator()
  • Lambdas (which are really just functor objects)

With that in mind, let's look at your example.


for_each(arr, arr + 5, Class());

Here, Class() is constructing an instance of class, and UnaryFunction is deduced to be Class. This is an instance of a class overloading operator(), so this is perfectly fine.


for_each(arr, arr + 5, ob);

Here, ob is an instance of Class, and since it's passed by value, this has the same effect as passing Class().


for_each(arr, arr + 5, Class);

Here, you're trying to pass a type, where a value is expected. This very simply is a no-no.


for_each(arr, arr + 5, ob());

Here, you are calling operator() on the object ob. This is bad for two reasons. 1; because Class::operator() expects a single int as a parameter, and this is missing. 2; because this will attempt to pass the value returned by operator() to for_each. Since you've defined Class::operator() to return void, this also makes no sense.

alter_igel
  • 6,899
  • 3
  • 21
  • 40