У меня есть класс тройной иерархии:
template<class T> class Singleton;
class Base;
class Sub : public Base, public Singleton<Sub>;
Я использую базовые автоматические указатели, поэтому Singleton является классом шаблона, а Sub передает себя как параметр шаблона. Я разрабатываю Singleton и Base, и публичный API позволяет любому добавлять свои собственные подклассы. Я на самом деле хочу настоящую тройную иерархию, как это:
template<class T> class Singleton;
class Base : public Singleton<Base>;
class Sub : public Base;
Так что сторонним разработчикам не нужно беспокоиться о шаблонах и сложности. Проблема в том, что моя реализация в Singleton теперь будет вызывать конструктор Base всякий раз, когда я создаю экземпляр Sub (поскольку параметром шаблона является Base).
Мне было интересно, если это можно сделать с помощью макросов препроцессора:
template<class T> class Singleton;
class Base : public Singleton<__CLASS_NAME__>;
class Sub : public Base;
куда __CLASS_NAME__
имя класса, которое будет заменено препроцессором. Теоретически это должно быть возможно, так как __PRETTY_FUNCTION__
макрос на самом деле возвращает имя класса. Проблема в том, что нельзя выполнять строковые манипуляции, чтобы удалить имя функции из __PRETTY_FUNCTION__
,
Любые идеи о том, как я могу сделать это так, чтобы класс Sub не знал о наследовании от Singleton<template>
учебный класс?
Так что сторонним разработчикам не нужно беспокоиться о шаблонах и
сложность.
Невозможно. Единственный способ спроектировать Base и Singleton, чтобы убрать требование передавать параметр шаблона в Singleton, — это вместо этого передать его в Base, что не является улучшением.
Кроме того, вполне ожидаемо, что разработчик C ++ сможет использовать CRTP.
Наконец, Singletons сосут самым ужасным образом. Если вы цените свое здравомыслие, немедленно удалите.
Я не очень знаком с CRTP (http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern) а как насчет сделать саму базу шаблоном?
template<class T> class Singleton;
template<class T> class Base : public Singleton<T>;
class Sub : public Base<Sub>;