Относительно «метода шаблона» (а не шаблона проектирования), следующий пример может помочь с за и против относительно того, что решать, что делать. Примером является создание подробного режима библиотеки, предназначенной для помощи при отладке / разработке.
С шаблонами
struct console_print
{
static void print(const string& msg) {std::cout<<msg;}
};
struct dont_print
{
static void print(const string& msg) {}
};
template<printer>
void some_function()
{
printer::print("some_function called\n");
}
Пользователь библиотеки может написать:
some_function<console_print>(); //print the verbose message;
some_function<dont_print>(); //don't print any messages.
Преимущество этого кода в том, что если пользователь не хочет, чтобы код печатался, тогда вызовы dont_print::print(msg)
полностью исчезают из кода (пустые статические классы легко оптимизируются). Такие отладочные сообщения можно затем вводить даже в критические области производительности.
Недостаток шаблонов заключается в том, что вам необходимо определить свою политику перед компиляцией. Вам также необходимо изменить сигнатуру функции / класса для любого шаблона.
без шаблонов
Выше можно, конечно, сделать что-то вроде:
struct printer
{
virtual void print(const std::string& msg) = 0;
}
struct console_print : public printer
{
void print(const std::string& msg) {std::cout<<msg;}
}
struct debug_print : public printer
{
void print(const std::string& msg) {}
}
Преимущество этого в том, что вы можете передавать типы принтеров своим классам и функциям и изменять их во время выполнения (может быть очень полезно для некоторых приложений). Однако стоимость заключается в том, что вызов виртуальной функции всегда выполняется, и поэтому пустой dont_print имеет небольшую стоимость. Это может или не может быть приемлемо для критических областей производительности.