0Pricing
C++ Academy · Aula

Especialização completa

Personalize templates para um tipo

Especialização completa é uma aula grátis de C++ Academy no CoddyKit. Esta é a aula 1 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de C++ Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de C++ Academy inclui 4 aulas no total.

Recapitulação: modelos

Um modelo permite que um trecho de código funcione para vários tipos. O compilador gera uma versão concreta para cada tipo utilizado.

  • A forma geral lida com todos os tipos.
  • Às vezes, um tipo precisa de um tratamento especial.
#include <iostream>

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

int main() {
    std::cout << maxOf(3, 9) << ' ' << maxOf(2.5, 1.5) << '\n';
    return 0;
}

O que é especialização completa?

A especialização completa fornece uma implementação totalmente separada para um tipo específico, substituindo o modelo geral apenas para esse tipo.

#include <iostream>

template <typename T>
void describe(T) { std::cout << "some type\n"; }

template <>
void describe(int) { std::cout << "an int\n"; }

int main() {
    describe(3.14);
    describe(42);
    return 0;
}

A sintaxe

Uma especialização completa começa com colchetes angulares vazios, template <>, e nomeia o tipo exato na especialização.

#include <iostream>

template <typename T>
struct TypeName { static const char* get() { return "unknown"; } };

template <>
struct TypeName<bool> { static const char* get() { return "bool"; } };

int main() {
    std::cout << TypeName<double>::get() << '\n';
    std::cout << TypeName<bool>::get() << '\n';
    return 0;
}

Especializando um modelo de classe

Modelos de classe inteiros podem ser especializados, dando a um tipo seus próprios membros e comportamento, distintos dos do modelo primário.

#include <iostream>

template <typename T>
struct Storage {
    T value;
    void show() { std::cout << "value: " << value << '\n'; }
};

template <>
struct Storage<bool> {
    bool value;
    void show() { std::cout << (value ? "true" : "false") << '\n'; }
};

int main() {
    Storage<int> s{5}; s.show();
    Storage<bool> b{true}; b.show();
    return 0;
}

Por que especializar?

A especialização lida com tipos que precisam de uma lógica diferente, como const char*, que precisa de comparação de cadeias de caracteres em vez de comparação de ponteiros.

#include <iostream>
#include <cstring>

template <typename T>
bool equal(T a, T b) { return a == b; }

template <>
bool equal(const char* a, const char* b) { return std::strcmp(a, b) == 0; }

int main() {
    std::cout << std::boolalpha;
    std::cout << equal(5, 5) << '\n';
    std::cout << equal("hi", "hi") << '\n';
    return 0;
}

Especializando um único membro

Em um modelo de classe, você pode especializar apenas uma função membro para determinado tipo e reutilizar o restante.

#include <iostream>

template <typename T>
struct Printer {
    void print(T v) { std::cout << v << '\n'; }
};

template <>
void Printer<char>::print(char v) {
    std::cout << "char: " << v << '\n';
}

int main() {
    Printer<int>{}.print(7);
    Printer<char>{}.print('A');
    return 0;
}

A correspondência exata vence a geral

Quando existe uma especialização completa para o tipo exato, o compilador sempre dá preferência a ela em vez do modelo primário.

#include <iostream>

template <typename T>
int rank() { return 0; }

template <>
int rank<double>() { return 99; }

int main() {
    std::cout << rank<int>() << ' ' << rank<double>() << '\n';
    return 0;
}

A especialização deve seguir o modelo primário

Uma especialização deve ser declarada depois que o modelo primário estiver visível; caso contrário, o compilador não terá nada para especializar.

#include <iostream>

template <typename T>
const char* kind() { return "generic"; }

template <>
const char* kind<float>() { return "float"; }

int main() {
    std::cout << kind<int>() << ' ' << kind<float>() << '\n';
    return 0;
}

Especializando modelos de std

Você pode especializar alguns modelos da biblioteca padrão, como std::hash, para os seus próprios tipos, permitindo que funcionem com contêineres baseados em hash.

#include <iostream>

struct Point { int x, y; };

template <typename T>
struct Hasher { size_t operator()(const T&) { return 0; } };

template <>
struct Hasher<Point> {
    size_t operator()(const Point& p) { return p.x * 31 + p.y; }
};

int main() {
    Hasher<Point> h;
    std::cout << h(Point{2, 3}) << '\n';
    return 0;
}

Especialização de Valores

Parâmetros de modelo que não são tipos podem ser especializados para valores específicos, o que é útil para tabelas em tempo de compilação.

#include <iostream>

template <int N>
struct Fib { static const int value = Fib<N-1>::value + Fib<N-2>::value; };

template <>
struct Fib<0> { static const int value = 0; };

template <>
struct Fib<1> { static const int value = 1; };

int main() {
    std::cout << Fib<10>::value << '\n';
    return 0;
}

Mantenha o Comportamento Consistente

Uma especialização deve manter o mesmo contrato conceitual do modelo principal; apenas a implementação deve mudar. Caso contrário, o código chamador terá surpresas.

#include <iostream>

template <typename T>
T zero() { return T{}; }

template <>
int zero<int>() { return 0; }

int main() {
    std::cout << zero<int>() << ' ' << zero<double>() << '\n';
    return 0;
}

Verificação Rápida

Teste sua compreensão da sintaxe de especialização total.

Recapitulação

Você aprendeu sobre especialização total:

  • fornece uma implementação dedicada para um único tipo exato
  • é escrita com template <> e o tipo concreto
  • o compilador sempre dá preferência a uma especialização exata
  • funciona para funções, classes, membros individuais e valores específicos

Em seguida, você verá a especialização parcial, que corresponde a padrões de tipos.

Perguntas Frequentes

A aula “Especialização completa” é grátis?

Sim — o texto completo de “Especialização completa” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de C++ Academy, atualize para CoddyKit PRO. O curso de C++ Academy inclui 4 aulas no total.

O que vou aprender em “Especialização completa”?

Personalize templates para um tipo Você pratica C++ Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar C++ Academy?

Nenhuma experiência prévia é necessária. C++ Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 1 de 4.

Quanto tempo leva a aula “Especialização completa”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de C++ Academy?

Sim. Cada aula de C++ Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. Especialização completa
  2. Especialização parcial
  3. SFINAE
  4. Padrões de enable_if
← Voltar para C++ Academy