Padrões de enable_if
Restrinja templates da maneira clássica
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
::typesomente 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_te 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.
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
- Especialização completa
- Especialização parcial
- SFINAE
- Padrões de enable_if