fbpx

Function objects are simple but don’t let that fool you. You can use them in clever solutions.

It’s more difficult to explain why you might want to use a function object if you don’t yet know what a function object is. So that’s mostly what this episode explains. What is a function object? They’re sometimes called functors for short.

In many ways, you can think of a functor as a more complicated way to write a method. That’s what I hope to explain because there are some unique benefits to writing a method in the form of a function object.

Alright, a method has a signature. Let’s say you have a method that can add two integers. How would you write this as a functor?

class add
{
public:
	add() {}

	int operator () (int first, int second)
	{
		return first + second;
	}
};

The big question now is why? What possible benefit could come from such a roundabout and complicated way of writing a method? Well, if this is all the functor was going to do, then I’d agree. You should just use a method. But you have a class now and that means it can have other class member variables that control it’s behavior.

The only way to change the behavior of a method is to pass in different arguments. But with a functor, you can construct the class with whatever information you want and even call other methods that can change or modify internal data members. Then when you want to use it as if it was a function, it can refer to its own internal data to do different things.

Listen to the full episode for more or read the full transcript below.

Transcript

You already know how to write a function. A lot of times, probably most of the time actually, I call functions methods. It’s the same thing at least in C++ and C#. Some languages might have differences between functions and methods such as one may be allowed to return values while the other can’t. I tend to use the two terms as if they’re the same thing.

The topic of today’s episode though is never called method objects. At least, I’ve never heard them called this. They’re always function objects or sometimes functors for short.

It’s more difficult to explain why you might want to use a function object if you don’t yet know what a function object is. So that’s where I’ll start today. What is a function object?

In many ways, you can think of a functor as a more complicated way to write a method. That’s what I hope to explain because there are some unique benefits to writing a method in the form of a function object.

Alright, a method has a signature. Let’s say you have a method that can add two integers. I know, you can just add them directly without needing to call a method but bear with me for a moment and think about a method that can add two integers.

It should return an integer, have a good name, we’ll call it “add”, hey, sometimes the simple names are best, and the method should take two arguments for the integers to be added.

Once you have the method declared, you implement it by coding the body of the method. This is where you add the two argument values and return the result.

Once the method is declared and implemented, you can call it from your code by first declaring an integer variable to hold the result. That’ll be called sum. Then you just write sum is assigned add open parenthesis, give the two numbers to be added, and then a closing parenthesis. The key to calling a method is to use the method name, the open and close parenthesis, and the proper number and type of arguments expected by the method. The return value if any is up to you to decide what to do with. Those parenthesis characters though are critical. They’re the key to letting the compiler know that you want to call the method using the supplied arguments.

I’ll explain how to do the same thing with a functor right after this message from our sponsor.

A functor needs a class. You could use a struct if you want but I don’t know why you’d ever want to do that. Stick with a class. Let’s call the class add. And give it a default constructor for now anyway so it can be constructed without any extra arguments. Then, this is what turns a regular class into a function object. You provide an implementation of the function call operator. This is the operator open and close parenthesis. Yes, that’s actually an operator. Remember I said that those parenthesis were key to letting the compiler know that you wanted to call a method? This is why. The open and close parenthesis are used here to mean that you want to define a method, the function call method, that will be called anytime somebody wants to use an instance of your class as if it was a method.

You actually implement the function call operator just like the add method before. It returns an integer and takes two integer arguments as parameters.

Now, to use the functor is a little different. You don’t just call add like before. This time, add is the name of a class not a method.

What you do is declare a local variable of type add. Let’s call this variable “fo” which stands for function object. You should be seeing a bit of the reason why it’s a function object now. You actually have an instance of your class involved.

then you declare an integer variable to hold the sum like before and write sum is assigned fo open parenthesis, give the two numbers to be added, then a closing parenthesis. That’s it. Notice how you still use the open and close parenthesis so it looks just like you’re calling a method. Only instead of using a method name, you use the name of your variable representing your function object class.

The big question now is why? What possible benefit could come from such a roundabout and complicated way of writing a method? Well, if this is all the functor was going to do, then I’d agree. You should just use a method. But you have an instance of an object now and that means it can have other class member variables that control it’s behavior.

The only way to change the behavior of a method is to pass in different arguments. But with a functor, you can construct the class with whatever information you want and even call other methods that can change or modify internal data members. Then when you want to use it as if it was a function, it can refer to its own internal data to do different things.
Maybe it has a third internal data member that it always adds to the two integers passed to it and returns that result instead.

You can even have multiple instances of your add class. This time, instead of calling them “fo”, maybe you call one of them add5 and the other will be add10. The add5 instance will add the two numbers you send it plus 5. While the add10 instance will do the same thing except add an additional 10 to the result.

Because these are instances of a type, you can pass them around to other methods or do anything that you do with a regular variable. Try doing that with a method. Sure, you can pass a method pointer but it lacks the customized instance data that you get with a class instance.