C++
Как передать вектор в шаблон C++
В C++ вектор в шаблонную функцию обычно передают так: const std::vector<T>& items. T делает функцию универсальной по типу элементов, const запрещает случайно менять вектор, а & не копирует весь контейнер при вызове
Минимальный пример:
#include <iostream>
#include <vector>
template <typename T>
void printVector(const std::vector<T>& items) {
for (const T& item : items) {
std::cout << item << ' ';
}
std::cout << '\n';
}
int main() {
std::vector<int> numbers {1, 2, 3};
printVector(numbers);
}
Вывод:
1 2 3
Что означает T
T — это параметр шаблона. При вызове printVector(numbers) компилятор сам понимает, что T равен int. Если передать std::vector<std::string>, T станет std::string
std::vector<std::string> names {"Ann", "Bob"};
printVector(names);
Та же функция работает с другим типом
Почему const reference
Если написать так:
void printVector(std::vector<T> items)
вектор будет копироваться. Для маленького примера это незаметно, но для большого списка плохо. Поэтому чаще используют:
const std::vector<T>& items
Это значит: передаем ссылку на существующий вектор, не копируем его и обещаем не менять
Если функцию нужно менять вектор
Тогда уберите const:
template <typename T>
void addDefault(std::vector<T>& items, const T& value) {
items.push_back(value);
}
Вызов:
std::vector<int> numbers {1, 2};
addDefault(numbers, 3);
После вызова вектор изменится
Частые ошибки
Первая ошибка — забыть #include <vector>. Вторая — писать vector<T> без std::, если не подключено пространство имен. Третья — передавать вектор по значению и случайно копировать его. Четвертая — делать const, а потом пытаться вызвать push_back. Пятая — ожидать, что шаблон примет вектор любого типа, хотя внутри кода используется операция, которой у типа нет
Например, если внутри функции есть sum += item, тип T должен поддерживать сложение
Пример суммы для числового вектора
Шаблон можно использовать не только для вывода, но и для расчета:
template <typename T>
T sumVector(const std::vector<T>& items) {
T sum {};
for (const T& item : items) {
sum += item;
}
return sum;
}
Вызов:
std::vector<int> numbers {1, 2, 3};
std::cout << sumVector(numbers) << '\n';
Вывод:
6
Здесь T sum {} создает начальное значение: для int это 0, для double — 0.0. Но такая функция подойдет не всем типам. Если передать вектор объектов, у которых нет оператора +=, компилятор покажет ошибку
Когда шаблон не нужен
Если функция должна работать только с vector<int>, шаблон не обязателен:
void printNumbers(const std::vector<int>& numbers)
Шаблон нужен, когда одна и та же логика должна работать с разными типами: int, double, string или вашими классами. Не добавляйте template, если он не решает реальную задачу
Как указать тип явно
Обычно компилятор сам выводит T, но тип можно указать явно:
printVector<int>(numbers);
Это редко нужно в простых функциях, но полезно понимать синтаксис. Если компилятор не может вывести тип из аргументов, явное указание помогает. В обычном случае printVector(numbers) читается проще
Для закрепления полезно собрать пример с vector<int> и vector<string> в одном файле. Так сразу видно, что меняется только тип данных, а функция остается той же
Мини-задача
Напишите шаблонную функцию countItems, которая принимает const std::vector<T>& и возвращает items.size(). Проверьте ее на vector<int> и vector<string>
Что почитать дальше по C++
Что почитать дальше по C++
Если нужен общий маршрут по теме, откройте рубрику C++. Для соседних задач пригодятся эти разборы:
- Как передать массив в функцию C++: размер, vector, array и span
- C++ с нуля: первый файл, переменные и вывод
- Enter в C++: перенос строки, std::endl и ввод через cin
- Microsoft Visual C++ 14.0: что это, зачем нужен и как исправить ошибку установки