Generics em C++: templates, para que servem e como usar

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course
```html

Introdução: O que são Generics (templates) em C++ e por que são necessários?



No mundo da programação em C++, um dos conceitos-chave que permite escrever código flexível, reutilizável e type-safe são os templates. Frequentemente são chamados de "generics" por analogia com outras linguagens, como Java ou C#, embora em C++ este conceito seja significativamente mais poderoso e profundo.



Imagine que você precisa escrever uma função para encontrar o elemento máximo em um array. Para números inteiros (int) seria uma função, para números de ponto flutuante (double) outra, para strings (std::string) uma terceira. Sem templates, você teria que duplicar código, o que leva a erros e dificulta a manutenção.



Generics (templates) resolvem esse problema. Eles permitem escrever código que funciona com qualquer tipo de dado, sem sacrificar a performance (ao contrário de funções virtuais ou void*). Templates são a base da biblioteca padrão do C++ (STL): containers (std::vector, std::map), algoritmos (std::sort, std::find) e smart pointers (std::shared_ptr) — todos são implementados usando templates.



Neste artigo, vamos analisar o que são templates em C++, como declará-los e usá-los corretamente, além de examinar exemplos práticos.



Parte principal: Como usar Generics (templates) em C++



1. Function Templates



A maneira mais simples de começar a trabalhar com generics é criar um function template. Em vez de escrever várias versões sobrecarregadas, você escreve uma, parametrizada pelo tipo.



Sintaxe:

template <typename T>T max(T a, T b) {    return (a > b) ? a : b;}


A palavra-chave template informa ao compilador que isso é um template. <typename T> declara o parâmetro de tipo T. Você pode usar class em vez de typename — não há diferença.



Exemplo de uso:

#include <iostream>#include <string>

template <typename T>T max(T a, T b) { return (a > b) ? a : b;}

int main() { std::cout << max(10, 20) << std::endl; // int: 20 std::cout << max(3.14, 2.71) << std::endl; // double: 3.14 std::cout << max(std::string("C++"), std::string("Python")) << std::endl; // string: Python return 0;}


Importante: O compilador gera uma versão separada da função para cada tipo usado. Isso é chamado de instanciação de template. Com isso, alcança-se a máxima performance — não há overhead de chamadas virtuais.



Vários parâmetros de tipo:

template <typename T1, typename T2>void printPair(T1 a, T2 b) {    std::cout << "(" << a << ", " << b << ")" << std::endl;}// printPair(1, "hello"); // Saída: (1, hello)


2. Class Templates



Class templates permitem criar estruturas de dados genéricas. O exemplo clássico é std::vector<T>. Você pode criar sua própria classe template, por exemplo, uma pilha simples:



template <typename T>class Stack {private:    T* data;    size_t size;    size_t capacity;public:    Stack(size_t cap = 10) : size(0), capacity(cap) {        data = new T[capacity];    }    ~Stack() { delete[] data; }

void push(const T& value) { if (size < capacity) { data[size++] = value; } }

T pop() { if (size > 0) { return data[--size]; } throw std::out_of_range("Stack is empty"); }

bool isEmpty() const { return ```

Blogs

Book Recommendations