При написании шаблона функции, такие как:
template<class T> void print(T const & collection)
При циклическом просмотре коллекции и разыменовании итератора все работает правильно, если у вас есть что-то вроде vector<int>
если вы не измените его на vector<int*>
, Какой лучший способ справиться с различиями в одной функции шаблона, не дублируя код?
Я бы написал одну шаблонную функцию do_print
что делегирует шаблон класса printer
, Шаблон класса — это функциональный объект, который выполняет красивую печать и для которого вы частично специализируете T*
просто позвонив симпатичной версии для печати на *t
,
Таким образом, нет никакого дублирования красивого печатного кода и незначительных неудобств для написания двух легких классов реализации (они оптимизируются любым современным компилятором, поэтому нет затрат времени выполнения).
Я предпочитаю это решение трюкам SFINAE, потому что частичная специализация класса дает вам гораздо больший контроль (и намного лучшие сообщения об ошибках), чем уловки перегрузки функций. Это также рекомендовано Александреску & Стандарты кодирования Саттера.
Кстати, этот код также будет работать для T**
потому что специализация для T*
делегаты в код для T
, Так T**
это отправить T*
и, наконец, T
, Фактически, произвольные уровни косвенности сводятся к печати элементов, на которые указывают указатели.
#include <iostream>
#include <vector>
namespace detail {
template<typename T>
struct printer
{
void operator()(T const& t)
{
std::cout << t; // your pretty print code here
}
};
template<typename T>
struct printer<T*>
{
void operator()(T const* t)
{
printer<T>()(*t); // delegate to printing elements (no duplication of prettty print)
}
};
}
template<typename T>
void do_print(T const& t)
{
detail::printer<T>()(t);
}
template<typename C>
void print(C const& collection)
{
for(auto&& c: collection)
do_print(c);
std::cout << "\n";
}
int main()
{
int a = 1;
int b = 2;
auto c = &a;
auto d = &b;
std::vector<int> v1 { a, b };
std::vector<int*> v2 { c, d };
std::vector<int**> v3 { &c, &d };
print(v1);
print(v2);
print(v3);
}
Выход на Live Work Space
Других решений пока нет …