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++. Для соседних задач пригодятся эти разборы:

Подписаться
Уведомить о
guest
0 комментариев
Старые
Новые Популярные

Настройки cookie

0
Оставьте комментарий! Напишите, что думаете по поводу статьи.x