Короткий, простой и недостаточный ответ: std::vector
имеет 2 параметра шаблона. Вы также должны включить некоторый интервал:
template<class T, class A, template<class, class>class C>
void print(C<T,A> const& cont) {
std::cout << "[ ";
bool bFirst = true;
for (const auto& i : cont) {
if (!bFirst)
std::cout << ", ";
bFirst = false;
print(i);
}
std::cout << " ]";
}
Чтобы перегрузка никогда не вызывалась.
Как только вы это сделаете, ваш код не будет работать, потому что у вас нет элемента - принтер. Поэтому замените свой другой l oop -printer на element-printer:
template<typename T>
void print(T const& i){
std::cout << i;
}
Живой пример .
Тестовый код:
std::vector<int> a={1,2,3};
print(a);
std::cout << "\n";
std::vector<std::vector<int>> b = {a, a, a};
print(b);
std::cout << "\n";
Вывод:
[ 1, 2, 3 ]
[ [ 1, 2, 3 ], [ 1, 2, 3 ], [ 1, 2, 3 ] ]
этого недостаточно, потому что вам действительно нужно сделать что-то более интересное, чтобы определить, «является ли этот объект итерируемым» и «похож ли этот объект на кортеж», если вам нужен более серьезный принтер общего назначения . Обнаружение шаблонов Cont<A,B>
- плохая замена.
Здесь - это код для определения возможности итерации чего-либо (игнорируйте неверно проверенный ответ, прочтите тот, на который я ссылался).
Затем выполните тест SFINAE на предмет «повторяется ли аргумент» в print
для того, который выполняет for(:)
l oop.
Следующее, что вам нужно сделать, это определить, объект подобен кортежу. Если это так, вы хотите распечатать каждый элемент кортежа. Это дает вам поддержку std::map
и std::unordered_map
. Обратите внимание, что std::array
является как кортежем, так и итерабельным.
Это немного сложнее, чем обнаружение «итеративного», и больше зависит от того, с каким стандартом C ++ вы работаете, потому что подобие кортежа расширение с новыми версиями C ++. Вы можете полениться и просто обнаружить std::pair
и std::tuple
, которые охватят 99% случаев использования.