C++ is Lazy: CRTP

In my previous post Recursion, List Manipulation and Lazy Evaluation I wrote about the characteristics of functional programming: The story about lazy evaluation in C++ is short. Sorry to say but I have forgotten templates. The two advanced techniques CRTP and expression templates are based on lazy evaluation.

CRTP

But what does CRTP mean? The acronym CRTP stands for the C++ idiom Curiously Recurring Template Pattern and means a technique in C++ in which a class Derived derives from a class template Base. The key is that Base has Derived as template argument.

Although the method func2 (line 8) of the class, Lazy is only declared but not defined, the compiler accepts the program. Because I don't call func2, I need no definition.

That is exactly the property that the CRTP uses because the definition of a method of class templates is only needed if called. The declaration of the method is totally sufficient for the instantiation of the base class. Therefore, you can implement static polymorphism.

Static Polymorphism

Static polymorphism is quite similar to dynamic polymorphism. But in contrary to dynamic polymorphism with virtual methods, the dispatch of the method calls will take place a compile time. Now, we are at the center of the CRTP idiom.

I use in the function template execute (line 29 - 32) static polymorphism. I invoke on each argument base the method base.interface. The method Base::interface in line 7 - 9 is the key point of the CRTP idiom. The methods dispatches to the implementation of the derived class: static_cast<Derived*>(this)->implementation(). That is possible because the method will be instantiated when called. At this point in time the derived classesDerived1,Derived2 andDerived3are fully defined. Therefore, the method Base::interfacecan use the details of its derived classes. Especially interesting is the method Base::implementation (line 10 - 12). This method plays the role of a default implementation for the static polymorphism for the class Derived3 (line 27).

Here is the output of the program.

Admittedly, the only purpose of the example was it to present you the mechanic behind the static polymorphism. A convincing example is still missing. Here we are.

Mixins with CRTP

Mixins are a popular concept in the design of classes to mix in new code. Therefore, it's a often used technique in Python to change the behaviour of a class by using multiple inheritances. In contrary to C++ it is legal in Python to have more than one definition of a method in a class hierarchy. Python uses simply that method that is first in the Method Resolution Order (MRO).

You can implement mixins in C++ by using CRTP. A prominent example is the class std::enable_shared_from_this. By using this class you can create objects that return a std::shared_ptr to themselves. You have to derive your class MySharedClasspublic from std::enable_shared_from_this. Now, your class MySharedClass has a method shared_from_this for creating std::shared_ptr to its objects. You can read the details about std::enable_shared_from_this in my post Specialities of std::shared_ptr.

An additional typical use-case for mixins is a class that you want to extend with the capability that their instances support the comparison for equality and inequality.

I have implemented for the classes Apple and Man the smaller operator (line 28 and 37). For my further reasoning, I will only use the class Man for simplicity reasons. The class Man is public derived (line 32 - 35) from the class Equality<Man>. I have implemented for classes of the kind Equality<Derived> the equality (line 9 - 14) and the inequality operator (line 16 - 21). The inequality operator uses the equality operator (line 20). The equality operator uses the fact that the smaller operator is implemented for Derived (line 13). The equality operator and inequality operator convert its operands: Derived const&: Derived const& d1 = static_cast<Derived const&>(op1).

Now, I can compare Apple and Man for equality and inequality.

What's next?

In addition to CRTP, expression templates are also based on the idea of lazy evaluation. Expression templates are "structures representing a computation at compile time, which structures are evaluated only as needed to produce efficient code for the entire computation" (https://en.wikipedia.org/wiki/Expression_templates). As needed, that is the point of lazy evaluation and therefore expression templates are the topic of my next post.

Go to Leanpub/cpplibrary"What every professional C++ programmer should know about the C++ standard library".Get your e-book. Support my blog.

Very nice post. I just stumbled upon your blog and wished to say that I have really enjoyed browsing your blog posts. After all I'll be subscribing to your rss feed and I hope you write again very soon!