Functor Design Pattern

Lesson Introduction

Welcome! Today, we're diving into an essential concept in functional programming: the Functor Design Pattern. You might ask, "What is a functor, and why should I care?"

As you might remember we talked about functors in the previous units. In C++ a "functor" usually refers to a class implementing the () operator, which can be called like a function. However, in more general terms, a functor is a different concept.

Generally speaking, Functors allow you to map a function over a structure, making your code clean and modular. By the end of this lesson, you'll know how to create and use functors in C++ to transform data structures effectively. Let’s get started!

Understanding Functors

First, let’s clarify what a functor is. In Functional Programming, a functor refers to an object, such as a class or a template class, that provides a method (transform or map) to apply a function to some specific element.

In more general terms, consider a template class F. This template class is considered a functor if it defines a map (or transform) method. This method should take two arguments:

  1. A value of type F<T1>.
  2. A function t that transforms a value of type T1 to a value of type T2.

The map (transform) method then applies the function to the value inside the structure F and returns a new structure F<T2> with the transformed value.

Let's see an example to understand this concept better.

Creating the Functor Class

First, let’s define the Functor class and understand each line of code step-by-step.

#include <iostream>
#include <optional>
#include <functional>

template<typename T>
class Functor {
public:
    // Define the transform method
    template<typename U>
    std::optional<U> transform(const std::optional<T>& value, std::function<U(T)> func) {
        if (value) {
            return func(*value);
        } else {
            return std::nullopt;
        }
    }
};
  1. template<typename T>: This specifies that Functor is a template class parameterized by T, which represents the type of the value inside the std::optional.
  2. template<typename U>: This specifies that the transform method is itself a template method, allowing different types for the input (T) and output (U) elements.
  3. std::optional<U> transform(const std::optional<T>& value, std::function<U(T)> func): This is the declaration of the transform method.
    • It takes two parameters:
      • const std::optional<T>& value: A constant reference to an optional holding an element of type T.
      • std::function<U(T)> func: A function object taking an input of type T and returning an output of type U.
    • It returns an optional containing a transformed element if the input optional has a value, or std::nullopt if the input optional is empty.
Sign up

Join the 1M+ learners on CodeSignal

Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal