Я не согласен с одним ответом выше, в котором говорится, что решение на основе шаблонов может иметь худшие издержки или время выполнения. Фактически, решения на основе шаблонов позволяют писать более быстрый код, устраняя необходимость в виртуальных функциях или вызове по указателю (хотя я согласен, что использование этого механизма все еще не накладывает значительных накладных расходов).
Предположим, что вы настраиваете свой интерфейс обработки, используя серию «черт», то есть частей обработки или функций, которые могут быть настроены клиентом для настройки интерфейса обработки. Представьте себе класс с тремя (чтобы увидеть пример) параметризацией обработки:
template <typename Proc1, Proc2 = do_nothing, Proc3 = do_nothing>
struct ProcessingInterface
{
static void process(mpz_class& element) {
Proc1::process(element);
Proc2::process(element);
Proc3::process(element);
}
};
Если у клиента разные «процессоры» со статической функцией «процесс», которые знают, как обрабатывать элемент, вы можете написать такой класс, чтобы «объединить» эти три обработки. Обратите внимание, что у класса do_nothing
по умолчанию есть пустой метод процесса:
class do_nothing
{
public:
static void process(mpz_class&) {}
};
У этих вызовов нет накладных расходов. Это обычные вызовы, и клиент может настроить обработку, используя ProcessingInterface<Facet1, Facet2>::process(data);
.
Это применимо только в том случае, если вы знаете различные «грани» или «процессоры» во время компиляции, что, как кажется, имеет место в вашем первом примере.
Также обратите внимание, что вы можете написать более сложный класс, используя средства метапрограммирования, такие как boost.mpl , для включения большего количества классов, итерации по ним и т. Д.