Давайте рассмотрим класс шаблона CRTP Print, который предназначен для печати производного класса:
template <typename T>
struct Print {
auto print() const -> void;
auto self() const -> T const & {
return static_cast<T const &>(*this);
}
private:
Print() {}
~Print() {}
friend T;
};
Поскольку я хочу специализировать печать на основе производного класса, как мы могли бы сделать это с переопределением, я полагаю,пока не реализуем метод.
Мы можем обернуть целое число и сделать это, например:
class Integer :
public Print<Integer>
{
public:
Integer(int i) : m_i(i) {}
private:
int m_i;
friend Print<Integer>;
};
template <>
auto Print<Integer>::print() const -> void {
std::cout << self().m_i << std::endl;
}
Пока это работает, скажем, я хочу напечатать универсальную версиюwrapper:
template <typename T>
class Wrapper :
public Print<Wrapper<T>>
{
public:
Wrapper(T value) : m_value(std::move(value)) {}
private:
T m_value;
friend Print<Wrapper<T>>;
};
Если я специализируюсь на методе печати со специализацией Wrapper, он компилируется и работает:
template <>
auto Print<Wrapper<int>>::print() const -> void
{
cout << self().m_value << endl;
}
Но если я хочу сказать «для всех специализаций Wrapper,do this ", это не сработает:
template <typename T>
auto Print<Wrapper<T>>::print() const -> void
{
cout << self().m_value << endl;
}
Если я выполню эту функцию через следующую основную функцию:
auto main(int, char**) -> int {
auto i = Integer{5};
i.print();
auto wrapper = Wrapper<int>{5};
wrapper.print();
return 0;
}
Печать компилятора:
50:42: error: invalid use of incomplete type 'struct Print<Wrapper<T> >'
6:8: error: declaration of 'struct Print<Wrapper<T> >'
Зачем ?Как я могу это сделать ?Это вообще возможно, или я должен сделать полную специализацию моего класса CRTP?