Немного опоздал на эту вечеринку, и я знаю, что ОП специально просит не "понтифицировать", как они уже знают о STL, однако ...
Есть старый Доктор. Интервью Доббса с Алексом Степановым, пионером в области общего программирования и основным участником STL. Очень поучительно несколько способов, особенно для решения вопроса о том, почему более стандартные методы ОО не используются в STL. Выделяется один абзац:
Даже сейчас наследование C ++ не очень полезно для общего программирования. Давайте обсудим почему. Многие люди пытались использовать наследование для реализации структур данных и контейнерных классов. Как мы теперь знаем, было мало успешных попыток. Наследование в C ++ и связанный с ним стиль программирования резко ограничены. Невозможно реализовать дизайн, который включает в себя столь же тривиальную вещь, как равенство, используя его. Если вы начнете с базового класса X в корне вашей иерархии и определите для этого класса оператор виртуального равенства, который принимает аргумент типа X, то выведите класс Y из класса X. Каков интерфейс равенства? Он имеет равенство, которое сравнивает Y с X. Используя животных в качестве примера (ОО люди любят животных), определяют млекопитающих и выводят жирафов из млекопитающих. Затем определите сопряжение функции-члена, где животное соединяется с животным и возвращает животное. Затем вы получаете жирафа от животного, и, конечно, у него есть функция сопряжения, где жираф спаривается с животным и возвращает животное. Это определенно не то, что вы хотите. Хотя спаривание не может быть очень важным для программистов на C ++, равенство есть. Я не знаю ни одного алгоритма, где какое-либо равенство не используется.
Для тех, кто предпочитает ответ Java на эту же головоломку, Джош Блох прилагает все усилия, чтобы изложить те же моменты в «Эффективной Java», пункт 8: соблюдайте общий контакт при переопределении.
Это хорошая глава, с хорошим примером того, как пытаться сохранить контракт равных, в то же время расширяя простой класс Point с добавленным цветом: класс ColorPoint. Далее он демонстрирует, что существует фундаментальное ограничение ООП: нет способа расширить инстанцируемый класс И добавить компонент-значение при сохранении контракта равных .
Конечно, утверждение Блоха сформулировано более кратко, но они оба (правильно) делают одни и те же выводы. Основное отличие состоит в том, что Java является (был) языком «чистого ОО» - все должно находиться в классе, даже те вещи, как алгоритмы, которые не являются объектами естественного характера.
И я думаю, что Блох может быть чувствителен к этой проблеме, потому что он видел, как она эффектно провалилась в библиотеке Java: наследование стека от Vector является одним из примеров заметной проблемы проектирования в Java.
Чуть позже в интервью Степанов продолжает:
Я принимал участие в нескольких дискуссиях в Bell Labs по поводу разработки шаблонов и довольно бурно спорил с Бьярне, что он должен делать шаблоны C ++ как можно более близкими к дженерикам Ada. Я думаю, что я так сильно спорил, что он решил против этого Я понял важность наличия шаблонных функций в C ++, а не просто шаблонных классов, как считали некоторые люди. Однако я подумал, что шаблонные функции должны работать как дженерики Ada, то есть они должны быть явно созданы. Бьярне не слушал меня и разработал механизм функций шаблонов, в котором шаблоны создаются неявно с использованием механизма перегрузки. Эта конкретная техника стала решающей для моей работы, потому что я обнаружил, что она позволяет мне делать много вещей, которые были невозможны в Аде. Я рассматриваю этот конкретный дизайн Бьярна как чудесную работу, и я очень рад, что он не последовал моему совету.