Почему шаблонные миксины в C++ не являются чем-то вроде основы?
Я часто использую шаблонные миксины в C++, но мне интересно, почему эта техника больше не используется. Кажется, что в конечном итоге в повторном использовании. Такое сочетание мощи и эффективности - одна из причин, по которой я действительно люблю C++ и не вижу, как я перехожу на язык JIT.
Эта статья: http://www.thinkbottomup.com.au/site/blog/C%20%20_Mixins_-_Reuse_through_inheritance_is_good - хороший справочный материал, если вы не знаете, что это такое, и так ясно описывает случай с точки зрения повторного использования и производительность.
2 ответа
Проблема с миксинами - это... строительство.
class Base1 { public: Base1(Dummy volatile&, int); };
class Base2 { public: Base2(Special const&, Special const&); };
А теперь мой супер миксин:
template <typename T>
struct Mixin: T {};
Вы заметили проблему здесь? Как, черт возьми, я должен передавать аргументы конструктору базового класса? Какой конструктор должен Mixin
предложить?
Это сложная проблема, и она не была решена до C++11, который улучшил язык для идеальной пересылки.
// std::foward is in <utility>
template <typename T>
struct Mixin: T {
template <typename... Args>
explicit Mixin(Args&&... args): T(std::forward<Args>(args...)) {}
};
Примечание: двойные проверки приветствуются
Так что теперь мы можем использовать миксины... и просто менять привычки людей:)
Конечно, хотим ли мы на самом деле это совершенно другой предмет.
Одной из проблем с миксинами (которую мы успешно пропустили в плохой статье) является изоляция зависимостей, которую вы полностью утратили... и тот факт, что пользователи LoggingTask
затем обязаны написать шаблонные методы. В очень больших базах кода больше внимания уделяется зависимостям, чем производительности, потому что зависимости сжигают человеческие циклы, а производительность - только циклы ЦП... и они обычно дешевле.
Шаблоны требуют, чтобы реализация была видна в модуле перевода, а не только во время компоновки (C++11 обращается к этому, если вы будете использовать только указатель или ссылку на экземпляры). Это серьезная проблема для низкоуровневого кода в корпоративных средах: изменения в реализации вызовут (могут быть или не будут автоматически) огромное количество библиотек и клиентов для перекомпиляции, а не просто потребуют повторного связывания.
Кроме того, каждый экземпляр шаблона создает отдельный тип, что означает, что функции, предназначенные для работы с любым из экземпляров шаблона, должны иметь возможность принимать их - либо сами вынуждены быть шаблонными, либо им нужна форма передачи обслуживания для полиморфизма времени выполнения (который это часто достаточно просто сделать: просто нужен абстрактный базовый класс, выражающий набор поддерживаемых операций, и некоторая функция "get me a accessor", которая возвращает производный объект с указателем на создание экземпляра шаблона и связанные объекты в таблице виртуальной отправки),
В любом случае, этими проблемами обычно можно управлять, но методы управления связью, зависимостями и используемыми интерфейсами гораздо менее известны, понятны и легко доступны, чем сама простая методика смешивания. То же самое относится к шаблонам и классу политики BTW.