A curiously repeating pattern template can be used to implement a kind of static polymorphism. For example:
#include <iostream> template< class Derived > struct Base { static void print ( ) { std::cout << Derived::number_to_print << '\n'; } }; struct Derived final : Base< Derived > { static constexpr unsigned int number_to_print = 27; }; int main ( ) { Derived::print(); }
It behaves as expected and prints 27 .
Now I would like to add checks to the base class to claim that derived classes meet certain requirements. In the above example, such checks may be:
#include <iostream> #include <type_traits> template< class Derived > struct Base { // --- Checks begin static_assert( std::is_same< decltype(Derived::number_to_print), unsigned int >::value, "static member `number_to_print' should be of type `unsigned int'" ); // --- Checks end static void print ( ) { std::cout << Derived::number_to_print << '\n'; } }; struct Derived final : Base< Derived > { static constexpr unsigned int number_to_print = 27; }; int main ( ) { Derived::print(); }
This does not work, because at the moment when the Base<Derived> is created, Derived declared only forward, i.e. is incomplete, and none of this is yet known, except that it is a struct.
I scratch my head, as I believe that these checks may be useful for users of the base class, but have not found a way to do this.
Is this possible ?, and if so, how?
c ++ c ++ 14 crtp
Kalrish
source share