C++ Academy · Aula

Padrões de enable_if

Restrinja templates da maneira clássica

Aula 4 de 413 etapas

Padrões de enable_if é uma aula grátis de C++ Academy no CoddyKit. Esta é a aula 4 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.

O que é enable_if?

std::enable_if é um pequeno traço que define condicionalmente um membro type. Quando sua condição é verdadeira, o tipo existe; quando é falsa, o modelo ao redor é removido por meio de SFINAE.

  • Está definido em <type_traits>.
  • É a ferramenta clássica para restringir modelos.
#include <iostream>
#include <type_traits>

template <typename T>
typename std::enable_if<std::is_integral<T>::value, T>::type
doubleIt(T v) { return v * 2; }

int main() {
    std::cout << doubleIt(21) << '\n';
    return 0;
}

Como Funciona

enable_if<Cond, T>::type é T somente quando Cond é verdadeiro. Se for falso, não há membro type, então a substituição falha.

#include <iostream>
#include <type_traits>

int main() {
    std::cout << std::boolalpha;
    std::cout << std::is_same<std::enable_if<true, int>::type, int>::value << '\n';
    return 0;
}

enable_if no Tipo de Retorno

O local mais comum é o tipo de retorno. A função só existe quando a condição é satisfeita.

#include <iostream>
#include <type_traits>

template <typename T>
typename std::enable_if<std::is_floating_point<T>::value, T>::type
half(T v) { return v / 2; }

int main() {
    std::cout << half(5.0) << '\n';
    return 0;
}

enable_if como Parâmetro de Modelo

Outro padrão coloca enable_if em um parâmetro de modelo com valor padrão, mantendo o tipo de retorno limpo.

#include <iostream>
#include <type_traits>

template <typename T, typename = typename std::enable_if<std::is_integral<T>::value>::type>
T triple(T v) { return v * 3; }

int main() {
    std::cout << triple(4) << '\n';
    return 0;
}

Atalho enable_if_t

O C++14 adicionou o alias std::enable_if_t<Cond, T>, permitindo omitir o excesso de typename ...::type.

#include <iostream>
#include <type_traits>

template <typename T>
std::enable_if_t<std::is_integral<T>::value, T>
negate(T v) { return -v; }

int main() {
    std::cout << negate(8) << '\n';
    return 0;
}

Combinando Duas Sobrecargas

Forneça condições complementares para que exatamente uma sobrecarga seja válida para qualquer tipo, sem ambiguidades.

#include <iostream>
#include <type_traits>

template <typename T>
std::enable_if_t<std::is_integral<T>::value, const char*>
category() { return "integer"; }

template <typename T>
std::enable_if_t<!std::is_integral<T>::value, const char*>
category() { return "non-integer"; }

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

Combinando Condições

Use operadores lógicos sobre os valores dos traços para expressar restrições mais elaboradas, como "integral e com sinal".

#include <iostream>
#include <type_traits>

template <typename T>
std::enable_if_t<std::is_integral<T>::value && std::is_signed<T>::value, T>
magnitude(T v) { return v < 0 ? -v : v; }

int main() {
    std::cout << magnitude(-12) << '\n';
    return 0;
}

Restringindo um Construtor

Você pode colocar enable_if no parâmetro de modelo de um construtor para permiti-lo apenas para tipos compatíveis.

#include <iostream>
#include <type_traits>

struct Wrapper {
    int value;
    template <typename T, typename = std::enable_if_t<std::is_integral<T>::value>>
    Wrapper(T v) : value(static_cast<int>(v)) {}
};

int main() {
    Wrapper w(42);
    std::cout << w.value << '\n';
    return 0;
}

Armadilha do Argumento de Modelo Padrão

Duas sobrecargas que diferem apenas por um parâmetro de modelo enable_if com valor padrão são vistas como redefinições. Dê a elas formas diferentes; por exemplo, coloque uma condição no tipo de retorno.

#include <iostream>
#include <type_traits>

template <typename T>
std::enable_if_t<std::is_integral<T>::value, void>
printKind() { std::cout << "int\n"; }

template <typename T>
std::enable_if_t<std::is_floating_point<T>::value, void>
printKind() { std::cout << "float\n"; }

int main() {
    printKind<int>();
    printKind<double>();
    return 0;
}

Comparação com Conceitos

Os conceitos do C++20 substituem a maior parte do uso de enable_if com uma sintaxe muito mais clara, mas enable_if continua essencial no código anterior ao C++20 e em alguns casos específicos.

#include <iostream>
#include <type_traits>

template <typename T>
std::enable_if_t<std::is_arithmetic<T>::value, T>
square(T v) { return v * v; }

int main() {
    std::cout << square(6) << ' ' << square(1.5) << '\n';
    return 0;
}

Um Exemplo Completo

Combine tudo: uma família de funções que formata inteiros e números de ponto flutuante de maneira diferente, com a seleção ocorrendo em tempo de compilação.

#include <iostream>
#include <type_traits>

template <typename T>
std::enable_if_t<std::is_integral<T>::value, void>
format(T v) { std::cout << "int[" << v << "]\n"; }

template <typename T>
std::enable_if_t<std::is_floating_point<T>::value, void>
format(T v) { std::cout << "float(" << v << ")\n"; }

int main() {
    format(10);
    format(3.5);
    return 0;
}

Verificação Rápida

Teste sua compreensão de enable_if.

Recapitulação

Você aprendeu os padrões clássicos de enable_if:

  • define ::type somente quando a condição é verdadeira, habilitando SFINAE
  • é colocado no tipo de retorno ou em um parâmetro de modelo com valor padrão
  • use o alias enable_if_t e combine traços com operadores lógicos
  • os conceitos o substituem no C++20, mas ele continua amplamente utilizado

Isso conclui o curso de Especialização de Modelos e SFINAE.

Grátis para começar

Aprenda C++ com um tutor de IA — grátis

Escreva e execute código real no seu navegador, obtenha ajuda instantânea de um tutor de IA 24/7 e continue de onde parou na web ou no app.

Cursos
51
Aulas
203

Perguntas Frequentes

A aula “Padrões de enable_if” é grátis?

Sim — o texto completo de “Padrões de enable_if” é 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 “Padrões de enable_if”?

Restrinja templates da maneira clássica 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 4 de 4.

Quanto tempo leva a aula “Padrões de enable_if”?

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