Это также особенно полезно для mixins (под которыми я подразумеваю классы, от которых вы наследуете для обеспечения функциональности), которые сами должны знать, над каким типом они работают (и, следовательно, должны быть шаблонами).
В Действующий C ++ , Скотт Мейерс в качестве примера предоставляет шаблон класса NewHandlerSupport . Он содержит статический метод для переопределения нового обработчика для определенного класса (так же, как std :: set_new_handler для оператора по умолчанию new), и оператор new, который использует обработчик. Чтобы предоставить обработчик для каждого типа, родительский класс должен знать, на какой тип он действует, поэтому он должен быть шаблоном класса. Параметр шаблона является дочерним классом.
Вы не могли бы сделать это без CRTP, так как вам нужно, чтобы шаблон NewHandlerSupport создавался отдельно, с отдельным статическим элементом данных для хранения текущего new_handler, для класса, который его использует.
Очевидно, что весь пример крайне не поточнобезопасен, но он иллюстрирует суть.
Мейерс предполагает, что CRTP можно рассматривать как «Сделай это для меня». Я бы сказал, что это обычно относится к любому миксину, и CRTP применяется в том случае, когда вам нужен шаблон миксина, а не просто класс миксина.