#ifndef CRTP_H #define CRTP_H ///////////////////////////////////////////////////////////////////// // crtp.h - Curiously Recurring Template Pattern // // // // Jim Fawcett, CSE687 - Object Oriented Design, Spring 2006 // ///////////////////////////////////////////////////////////////////// /* The Curiosly Recurring Template Pattern (Coplien, C++ Report, 1996) is implemented with a pair of classes, like this: template class base { ... }; class derived : public base { ... }; We use it when we want to factor some processing into a base class so that it does not have to be repeated in every class that derives from it. However, some of the processing needs to use the name of the derived class. The code below follows closely an example discussed by Rainer Grimm here: http://www.modernescpp.com/index.php/c-is-still-lazy. My expansion of his code provides the logical operators: ==, !=, and > for any class Derived : public Compare that implements operator<. */ template class Compare {}; // uses Derived::operator< to define global operator== template bool operator==(Compare const& leftOp, Compare const& rightOp) { Derived const& dLft = static_cast(leftOp); // cast to base when called Derived const& dRgt = static_cast(rightOp); // cast to base when called return !(dLft < dRgt) && !(dRgt < dLft); } // uses Derived::operator< to define, indirectly, global operator!= template bool operator!=(Compare const& leftOp, Compare const& rightOp) { Derived const& dLft = static_cast(leftOp); Derived const& dRgt = static_cast(rightOp); return !(dLft == dRgt); } // uses Derived::operator< to define global operator> template bool operator>(Compare const& leftOp, Compare const& rightOp) { Derived const& dLft = static_cast(leftOp); Derived const& dRgt = static_cast(rightOp); return !(dLft < dRgt); } #endif