Skip to content

A STL

A STL (Standard Template Library) é uma das maiores forças do C++. Ela fornece containers eficientes, algoritmos genéricos e iteradores que permitem escrever código conciso e reutilizável. Este artigo mostra como usar templates no básico e como a STL resolve problemas comuns do dia a dia.

Sem templates, precisaríamos escrever funções separadas para cada tipo, resultando em duplicação de código e dificuldade de manutenção.

int dobrar(int x) { return x * 2; }
double dobrar(double x) { return x * 2; }
int main() {
std::cout << dobrar(2) << "\n";
std::cout << dobrar(2.5) << "\n";
}

Templates permitem escrever código genérico que funciona com qualquer tipo. O compilador gera automaticamente as versões específicas necessárias.

template<typename T>
T dobrar(T x) { return x * 2; }
int main() {
std::cout << dobrar(2) << "\n"; // deduz int
std::cout << dobrar(2.5) << "\n"; // deduz double
}

A dedução de tipo funciona automaticamente na maioria dos casos, mas você pode especificar explicitamente com dobrar<int>(2) quando necessário. As palavras-chave typename e class são equivalentes em templates simples.

Classes também podem ser templates:

template<typename T>
struct Caixa { T valor; };
int main() {
Caixa<int> c{42};
Caixa<std::string> s{"oi"};
std::cout << c.valor << " " << s.valor << "\n";
}

A STL oferece três componentes principais: containers para armazenar dados, iteradores para acessar esses dados, e algoritmos para manipulá-los.

Os containers essenciais incluem std::vector para arranjos dinâmicos, std::string para texto, e std::unordered_map para dicionários de chave-valor baseados em hash.

Prefira algoritmos da STL a loops manuais quando existir equivalente. Eles são otimizados e expressam a intenção claramente:

#include <vector>
#include <algorithm>
#include <numeric>
#include <iostream>
int main() {
std::vector<int> v{3,1,4,1,5};
std::sort(v.begin(), v.end());
int soma = std::accumulate(v.begin(), v.end(), 0);
std::cout << soma << "\n";
}

O unordered_map funciona como um dicionário eficiente:

#include <unordered_map>
#include <string>
#include <iostream>
int main() {
std::unordered_map<std::string,int> freq;
for (auto s : {"um","um","dois"}) freq[s]++;
std::cout << freq["um"] << " " << freq["dois"] << "\n";
}

O C++17 introduziu std::string_view, uma visão leve sobre strings que evita cópias desnecessárias:

#include <string_view>
#include <iostream>
void print(std::string_view s) { std::cout << s << "\n"; }

O C++20 trouxe a biblioteca <ranges>, permitindo pipelines elegantes com views e algoritmos:

#include <ranges>
#include <vector>
#include <iostream>
int main() {
using std::views::filter;
using std::views::transform;
std::vector<int> v{1,2,3,4,5,6};
auto evens_squared = v
| filter([](int x){ return x % 2 == 0; })
| transform([](int x){ return x * x; });
for (int x : evens_squared) std::cout << x << "\n";
}

Também em C++20, std::span oferece uma visão segura sobre dados contíguos sem assumir propriedade:

#include <span>
#include <iostream>
void soma(std::span<const int> xs) {
int s = 0; for (int x : xs) s += x; std::cout << s << "\n";
}

O método contains em unordered_map simplifica verificações:

#include <unordered_map>
bool tem(const std::unordered_map<int,int>& m, int k) {
return m.contains(k); // C++20
}

O C++23 adicionou std::ranges::to para coletar resultados de pipelines diretamente em containers:

#include <ranges>
#include <vector>
int main() {
std::vector<int> v{1,2,3,4};
auto out = v | std::views::transform([](int x){return x+1;})
| std::ranges::to<std::vector<int>>();
}

Sempre inclua os headers corretos para cada componente da STL que utilizar. Tenha cuidado pois inserções e remoções em containers podem invalidar iteradores existentes. Use auto para simplificar tipos verbosos, e auto& quando precisar modificar elementos durante iteração. A STL se integra perfeitamente com smart pointers quando você precisa de polimorfismo em containers.

Para compilar código com diferentes padrões:

  • C++17: g++ -std=c++17 arquivo.cpp -o exec
  • C++20: g++ -std=c++20 arquivo.cpp -o exec
  • C++23: g++ -std=c++23 arquivo.cpp -o exec