Ciekawie powtarzający się wzorzec szablonu może być użyty do zaimplementowania pewnego rodzaju statycznego polimorfizmu. Na przykład:CRTP - Sprawdzanie od klasy bazowej, że wyprowadzony spełnia wymagania
#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();
}
Zachowuje się zgodnie z oczekiwaniami i drukuje 27
.
Teraz chciałbym dodać kontrole do klasy bazowej, aby stwierdzić, że klasy pochodne spełniają określone wymagania. W przykładzie podanym powyżej, takie kontrole mogą być:
#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();
}
To nie działa, ponieważ w miejscu, gdzie Base<Derived>
jest tworzony, Derived
został tylko do przodu oświadczył, czyli to jest niekompletne, i nic z tego jest jeszcze znany poza faktem, że jest to struktura.
Podrapałam się w głowę, ponieważ uważam, że te sprawdzenia mogą okazać się pomocne dla użytkowników klasy podstawowej, ale nie znaleźliśmy żadnego sposobu, aby to zrobić.
Czy to możliwe ?, a jeśli tak, to w jaki sposób?
[Ta strona] (http://www.gotw.ca/publications/mxc++-item-4.htm) jest bardzo przydatna. – Kalrish