Step 2 of 8
Templates over containers
A template parameter can appear anywhere in a signature, including inside other types. const std::vector<T>& accepts a vector of anything, and T is deduced from the vector you pass.
#include <iostream>
#include <string>
#include <vector>
template <typename T>
T sum(const std::vector<T>& v) {
T s{}; // T{} is "zero" for numbers, "" for strings
for (const auto& x : v) s += x;
return s;
}
template <typename T>
bool contains(const std::vector<T>& v, const T& target) {
for (const auto& x : v) {
if (x == target) return true;
}
return false;
}
int main() {
std::cout << sum(std::vector<int>{1, 2, 3}) << "\n";
std::cout << sum(std::vector<double>{0.5, 0.25}) << "\n";
std::cout << sum(std::vector<std::string>{"ab", "cd", "e"}) << "\n";
std::vector<std::string> pets = {"cat", "dog"};
std::cout << contains(pets, std::string("dog")) << contains(pets, std::string("owl")) << "\n";
}
6
0.75
abcde
10
How it works
T s{};is value initialization:0for numbers, an empty string forstd::string, an empty vector for vectors. It's the generic way to say "start from nothing".- Take elements by
const auto&and the target byconst T&, so strings and other big types aren't copied. - In
contains(pets, std::string("dog")), both arguments must agree onT. Passing a plain"dog"literal would make the compiler deduceT = std::stringfrom the vector butconst char*from the literal, and that's a deduction error.
Your task
Counting matches is the same loop as contains, but with a counter instead of an early return. It only needs == from the element type.
Your turn: write template <typename T> int count_equal(const std::vector<T>& v, const T& value) that counts elements equal to value.