Desafio C++
Soma de arrays com template e instanciação explícita
Enunciado
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.
Requisitos
- A função deve ser um template com
template<typename T>. - Deve somar os elementos do índice
inicioatéfim - 1. - Deve funcionar para
int,doubleefloat. - O
maindeve chamar a função para os três tipos e imprimir as somas. - Deve haver uma instanciação explícita de pelo menos um tipo.
Código inicial
#include <iostream>
// TODO: template somarArray
int main() {
// TODO: crie arrays e chame somarArray
return 0;
}
Saída esperada
Soma int: 15
Soma double: 6.6
Soma float: 7.5
Ver dica
Use um loop for (int i = inicio; i < fim; ++i) e acumule em uma variável T soma = T{};. A instanciação explícita pode ser feita com template double somarArray<double>(double*, int, int); fora do main.
Mostrar solução
#include <iostream>
// Template genérico: soma elementos de um array no intervalo [inicio, fim)
template<typename T>
T somarArray(T* arr, int inicio, int fim) {
T soma = T{}; // inicializa com zero do tipo T
for (int i = inicio; i < fim; ++i) {
soma += arr[i];
}
return soma;
}
// Instanciação explícita para double (demonstra o conceito)
template double somarArray<double>(double*, int, int);
int main() {
int ints[] = {1, 2, 3, 4, 5};
double doubles[] = {1.1, 2.2, 3.3};
float floats[] = {1.5f, 2.5f, 3.5f};
// Dedução: T = int
std::cout << "Soma int: " << somarArray(ints, 0, 5) << '\n';
// Dedução: T = double (também instanciada explicitamente acima)
std::cout << "Soma double: " << somarArray(doubles, 0, 3) << '\n';
// Dedução: T = float
std::cout << "Soma float: " << somarArray(floats, 0, 3) << '\n';
return 0;
}
Passo a passo
- Declaramos o template
somarArraycomtemplate<typename T>, que aceita um ponteiroT*, e dois índicesinicioefim. - Inicializamos
T soma = T{};para garantir que a soma comece com o valor zero do tipoT(0 para int, 0.0 para double, etc.). - O loop
for (int i = inicio; i < fim; ++i)percorre o intervalo semiaberto[inicio, fim). - Dentro do loop, acumulamos
soma += arr[i];. - Após o loop, retornamos
soma. - Fora do
main, escrevemostemplate double somarArray<double>(double*, int, int);para forçar a instanciação explícita paradouble, mesmo que já ocorra implicitamente. - No
main, criamos três arrays e chamamossomarArraypara cada um. O compilador deduzTa partir do tipo do ponteiro. - As somas são impressas com os rótulos corretos.
Por que funciona
O template permite que a mesma lógica de soma seja aplicada a diferentes tipos numéricos. A dedução de tipos determina T a partir do ponteiro passado. A instanciação explícita força a geração do código para double antes mesmo de ser usada, o que pode ser útil para reduzir o tempo de compilação em projetos grandes ou para exportar templates em bibliotecas. A especialização não foi necessária aqui, mas o conceito de instanciação é demonstrado.
Erros comuns
- Esquecer de inicializar
somacomT{}: se usarT soma;, o valor inicial é indefinido, gerando resultados errados. - Passar o tamanho errado do array: se
fimfor maior que o número de elementos, o programa acessa memória inválida. - Declarar a instanciação explícita dentro do
main: isso não é permitido; deve ser feita no escopo global ou de namespace. - Usar
intpara acumulardouble: sesomafosseint, a parte fracionária seria perdida. O tipoTgarante a precisão correta.
Outra forma de resolver
Se quiser evitar ponteiros crus, pode usar std::vector<T> e iteradores:
template<typename T>
T somarArray(const std::vector<T>& v, int inicio, int fim) {
T soma = T{};
for (int i = inicio; i < fim; ++i) soma += v[i];
return soma;
}
Isso é mais seguro e idiomático em C++ moderno, mas exige incluir <vector>.
Saída esperada
Soma int: 15
Soma double: 6.6
Soma float: 7.5