Я хочу начать этот вопрос, сказав, что он связан с парадигмой и что я только пытаюсь прояснить некоторые концепции. Итак, я программирую на Python уже около 2 лет, окунулся в Java, но не слишком сильно, и я хочу углубиться в C ++. Я использовал это раньше, но не для больших проектов с большим количеством вовлеченного дизайна.
Когда я впервые начал исследовать его, я полагал, что он адресован ООП аналогично Java, где все должно реализовывать интерфейс. Затем я наткнулся на концепцию шаблоны который я немедленно хотел бы обойти, чтобы обеспечить полиморфное поведение примитивам (Интс, поплавки), который не реализовал это (в основном то, что Python делал с помощью duck-typing и без формальных интерфейсов). Но вскоре я обнаружил, что шаблоны используются для обеспечения одинакового поведения не примитивных типов.
Итак, мой вопрос: что является причиной использования классического полиморфизма над шаблонами, и каков общий подход к этому в сообществе C ++?
РЕДАКТИРОВАТЬ Только что нашел этот который в значительной степени отвечает на вопрос (статический полиморфизм действительно нужно обернуть голову вокруг этой терминологии).
Рискуя делать широкие обобщения, шаблоны в основном используются аналогично Generics в Java — они позволяют создавать класс или функцию, которые могут использоваться со многими различными типами данных. принимать std::list
, часть стандартной библиотеки шаблонов. Вы можете сделать связанный список целых чисел с std::list<int>
или список объектов с std::list<MyClass>
, Другой пример std::thread
, который использует шаблоны для получения функции (или лямбды или функтора) и ее аргументов для запуска в другом потоке.
Что касается выбора между функцией f(SomeInterface x)
и шаблон функции f(T x)
, это действительно зависит от контекста и является несколько субъективным. Некоторые вещи, которые следует принять во внимание:
Шаблоны функций и шаблоны классов разрешаются во время компиляции, поэтому вы можете повысить производительность. Тем не мение,
Компиляторы C ++ исторически генерируют едва поддающийся расшифровке мусор для ошибок шаблона. Clang проделал определенную работу, чтобы улучшить это, и другие компиляторы становятся лучше, чтобы соответствовать Clang. Все становится лучше, но все еще довольно уродливо.
Не бойтесь использовать традиционный полиморфизм с интерфейсами и классами реализации. Хотя в некоторых случаях вместо полиморфизма используются шаблоны (см. C ++ std::thread
который использует шаблоны против Java Thread
который использует Runnable
интерфейс), полиморфизм все еще чрезвычайно распространен в библиотеках и проектах C ++.
Короче говоря, не стесняйтесь использовать шаблоны, но не рассматривайте их как замену полиморфизму. Посмотрите на популярную библиотеку C ++, и вы обязательно найдете много полиморфизма. Возьмите OGRE, популярный графический движок C ++. Если вы посмотрите на его список классов, вы найдете много интерфейсов (таких как WindowEventListener
а также FrameListener
) из которого пользователь может получить класс для взаимодействия с библиотекой.
Других решений пока нет …