Da trilha de C++ Este conceito ainda não saiu como card do dia. ir para o card de hoje

C++ Genéricos Intermediário

Templates de função

Templates de função permitem escrever uma única função que funciona para vários tipos de dados. A palavra-chave template introduz um parâmetro de tipo genérico, como typename T, que será substituído pelo tipo real no momento da chamada. O compilador deduz automaticamente esse tipo a partir dos argumentos passados, gerando uma versão específica da função — isso é a instanciação.

Além da dedução automática, é possível especializar um template para um tipo específico, fornecendo uma implementação diferente. Isso é útil quando o comportamento genérico não é adequado para certos tipos. A especialização pode ser total (para um tipo concreto) ou parcial (para, por exemplo, ponteiros).

Neste card, você verá como declarar templates de função, como o compilador deduz os tipos, como forçar uma instanciação explícita e como criar especializações. Esses recursos são a base da programação genérica em C++ e aparecem em toda a biblioteca padrão, como em std::sort e std::vector.

Pontos-chave

  • template<typename T> declara um parâmetro de tipo genérico T que será substituído na chamada.
  • O compilador deduz T a partir dos tipos dos argumentos passados para a função.
  • A instanciação é a geração do código concreto para um tipo específico; pode ser implícita ou explícita.
  • Especialização permite fornecer uma implementação diferente para um tipo particular.
  • Templates são verificados em tempo de compilação, garantindo type safety sem custo em tempo de execução.
template_funcoes.cpp
#include <iostream>
#include <string>

// Template genérico: funciona para qualquer tipo que suporte operator+
template<typename T>
T soma(T a, T b) {
    return a + b;
}

// Especialização total para const char* (evita somar ponteiros)
template<>
const char* soma<const char*>(const char* a, const char* b) {
    static std::string resultado;
    resultado = std::string(a) + std::string(b);
    return resultado.c_str();
}

int main() {
    // Dedução automática: T = int
    std::cout << soma(3, 4) << '\n';               // 7

    // Dedução automática: T = double
    std::cout << soma(2.5, 3.5) << '\n';           // 6

    // Dedução automática: T = std::string
    std::cout << soma(std::string("Olá, "), std::string("mundo!")) << '\n';

    // Chamada da especialização para const char*
    std::cout << soma("Bom ", "dia!") << '\n';

    // Instanciação explícita: força a geração para double
    std::cout << soma<double>(1, 2) << '\n';       // 3

    return 0;
}

Exercícios

  1. 1
    Fácil

    Maior de dois valores

    Crie um template de função maior que recebe dois valores de qualquer tipo e retorna o maior deles. Use template<typename T>. No main, chame a função com int, double e std::string e imprima os resultados.

    Resolver
  2. 2
    Médio

    Especialização para ponteiros

    Crie um template de função imprimir que exibe um valor na tela. Para tipos genéricos, imprima Valor: <valor>. Especialize o template para ponteiros (T*) de modo que imprima Ponteiro para: <valor apontado>. No main, chame imprimir com um int, um double e um int*.

    Resolver
  3. 3
    Desafio

    Soma de arrays com template e instanciação explícita

    Crie um template de função somarArray que recebe um ponteiro para o primeiro elemento de um array, um índice inicial e um índice final (exclusivo), e retorna a soma dos elementos no intervalo. A função deve funcionar para int, double e float. No main, crie arrays desses três tipos e chame a função para cada um, imprimindo as somas. Além disso, force uma instanciação explícita para int usando template double somarArray<double>(double*, int, int); (ou similar) para demonstrar o conceito.

    Resolver

Continue estudando