Общий алгоритм вызова print для каждого элемента в коллекции

При написании шаблона функции, такие как:

template<class T> void print(T const & collection)

При циклическом просмотре коллекции и разыменовании итератора все работает правильно, если у вас есть что-то вроде vector<int> если вы не измените его на vector<int*>, Какой лучший способ справиться с различиями в одной функции шаблона, не дублируя код?

1

Решение

Я бы написал одну шаблонную функцию 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

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]