Sto testando una classe contenuta nei file "Numeri.h" e "Numeri.cpp". Tutte le funzioni non hanno problemi eccetto la funzione
codice:
Numeri divisione1(T4 num18);
che continua a generare principalmente il seguente errore: "Riga 23 del main.cpp undefined reference to `Numeri Numeri::divisione1<int, void>(int)'". Ho provato a correggere la funzione in svariati modi ma senza riuscirci. Inoltre ho scoperto che cambiando tipo passato, l'errore cambia di conseguenza in questo modo: es. se passo alla funzione un tipo double l'errore diventa: "Riga 23 del main.cpp undefined reference to "`Numeri Numeri::divisione1<double, void>(double)'".Di seguito il main e la classe rispettivamente nell'header e nell'eseguibile.
codice:
int main()
{
Numeri n, m;
n.ottieni1();
cout<<"n-> ";
n.mostra1();
int a;
cin>>a;
m=n.divisione1(a); //riga 23
cout<<"n-> ";
n.mostra1();
cout<<"s-> ";
s.mostra1();
cout<<"a-> "<<a<<endl;
system("pause");
}
Questo e' il main, dove "a" potrebbe anche essere un numero scritto per esteso, anche di tipi differenti.
codice:
#ifndef NUMERI_H
#define NUMERI_H
//librerie standard
#include<iostream>
#include<cstring>
#include<fstream>
#include<cstdlib>
#include<iomanip>
#include<typeinfo>
#include<cmath>
#include<string>
using namespace std;
//Classe concreta "Numeri"
class Numeri
{
private:
//campi
static const int V1_SIZE1=4;
int vet5_num1[V1_SIZE1]={0}; //per decimali vet5_num1[0] solo fino a 999->q.max->1000000000000000000
//metodi
void aumenta1(int pos1);
void diminuisci1(int pos2);
void divisoDieci(int num2);
public:
//costanti
static const int MAX1=1000000000;
//costruttori
Numeri();
Numeri(int vet12_num25[]);
//distruttori
~Numeri();
//metodi
void ottieni1();
void converti1(string s3);
void converti2(long double ld7);
void converti3(unsigned long long int uli7);
void converti4(Numeri &ptr8_ele2_num7);
template <typename T1, typename=typename std::enable_if<std::is_arithmetic<T1>::value>::type>
Numeri addizione1(T1 num8);
Numeri addizione2(Numeri &ptr9_ele4_num10);
template <typename T2, typename=typename std::enable_if<std::is_arithmetic<T2>::value>::type>
Numeri sottrazione1(T2 num11);
Numeri sottrazione2(Numeri &ptr10_ele6_num13);
template <typename T3, typename=typename std::enable_if<std::is_arithmetic<T3>::value>::type>
Numeri moltiplicazione1(T3 num14);
Numeri moltiplicazione2(Numeri &ptr11_ele8_num16);
template <typename T4, typename=typename std::enable_if<std::is_arithmetic<T4>::value>::type>
Numeri divisione1(T4 num18);
Numeri operator/(unsigned long long int n);
Numeri divisione2(Numeri &ptr12_ele11_num20);
template <typename T5, typename=typename std::enable_if<std::is_arithmetic<T5>::value>::type>
int compareto1(T5 num22);
int compareto2(Numeri &ptr13_ele14_num24);
//metodi grafica
void mostra1();
//metodi ritorno campi
int getValore1(int pos3);
long double getValore2();
string getValore3();
};
#endif
Questo e' il Numeri.h
codice:
//classi aggiunte
#include "Numeri.h"
//costruttori
Numeri::Numeri() {}
Numeri::Numeri(int vet12_num25[]) {...}
//distruttori
Numeri::~Numeri() {}
//metodi
void Numeri::ottieni1() {...}
void Numeri::converti1(string s3) {...}
void Numeri::converti2(long double ld7) {...}
void Numeri::converti3(unsigned long long int uli7) {...}
void Numeri::converti4(Numeri &ptr8_ele2_num7) {...}
template <typename T1, typename=typename std::enable_if<std::is_arithmetic<T1>::value>::type>
Numeri Numeri::addizione1(T1 num8) //per numeri piccoli tipo costanti piccole
{
Numeri ele3_num9;
switch(sizeof(num8))
{
case 4: //int
ele3_num9.converti3(num8);
break;
case 8: //double (con virgola)
default:
ele3_num9.converti2(num8);
break;
}
return ele3_num9=this->addizione2(ele3_num9);
}
Numeri Numeri::addizione2(Numeri &ptr9_ele4_num10) {...}
template <typename T2, typename=typename std::enable_if<std::is_arithmetic<T2>::value>::type>
Numeri Numeri::sottrazione1(T2 num11) {...}
Numeri Numeri::sottrazione2(Numeri &ptr10_ele6_num13){...}
template <typename T3, typename=typename std::enable_if<std::is_arithmetic<T3>::value>::type>
Numeri Numeri::moltiplicazione1(T3 num14) {...}
Numeri Numeri::moltiplicazione2(Numeri &ptr11_ele8_num16) {...}
template <typename T4, typename=typename std::enable_if<std::is_arithmetic<T4>::value>::type>
Numeri Numeri::divisione1(T4 num18) //sistemare manca parte decimali e controllo per denominatore maggiore del numeratore
{
Numeri ele10_num19;
switch(sizeof(num18))
{
case 4: //int
{
ele10_num19=*this;
int j1=0;
//scopro se il numero da dividere � composto da 0 a sinistra e quanti sono
while((num18%10)==0)
{
num18=num18/10;
++j1;
}
if(j1!=0)
ele10_num19.divisoDieci(j1);
if(num18==1)
return ele10_num19;
//se il divisore � minore di 5 uso questo algoritmo
if(num18<5)
{
int resto=ele10_num19.vet5_num1[3]%num18;
ele10_num19.vet5_num1[3]/=num18;
ele10_num19.vet5_num1[2]+=(resto*MAX1);
resto=ele10_num19.vet5_num1[2]%num18;
ele10_num19.vet5_num1[2]/=num18;
ele10_num19.vet5_num1[1]+=(resto*MAX1);
resto=ele10_num19.vet5_num1[1]%num18;
ele10_num19.vet5_num1[1]/=num18;
return ele10_num19;
}
//altrimenti se � un numero inderiore di MAX1/10 uso quest'altro algoritmo
else if(num18<100000000)
{
string s=ele10_num19.getValore3(), s_temp, soluzione;
int j=0, num;
while(j<s.size())
{
if(s[j]==',')
{
j++;
continue;
}
s_temp+=s[j++];
num=stoi(s_temp);
if(num<num18)
{
soluzione+='0';
continue;
}
s_temp=to_string(num%num18);
soluzione+=to_string(num/num18);
}
ele10_num19.converti1(soluzione);
return ele10_num19;
}
//altrimenti converto ed uso l'algoritmo generale
ele10_num19.converti3(num18);
}
break;
case 8: //double (con virgola)
default:
ele10_num19.converti2(num18);
break;
}
//algoritmo generale per vedere se un Numero � una potenza di 10
int j1=0;
if(ele10_num19.vet5_num1[0]!=0)
ele10_num19=this->divisione2(ele10_num19);
else
{
bool flag5=true;
while(flag5)
{
if((ele10_num19.vet5_num1[1]%10)==0)
{
ele10_num19.divisoDieci(1);
++j1;
}
else
flag5=false;
}
if(j1!=0)
this->divisoDieci(j1);
//uso l'algoritmo generale di divisione
ele10_num19=this->divisione2(ele10_num19);
//risistemo il dividendo
for(;j1>0; j1--)
*this=this->moltiplicazione1(10);
}
return ele10_num19;
}
Numeri Numeri::operator/(unsigned long long int n)
{
return this->divisione1(n);
}
//algoritmo generale di divisione
Numeri Numeri::divisione2(Numeri &ptr12_ele11_num20) {...}
template <typename T5, typename=typename std::enable_if<std::is_arithmetic<T5>::value>::type>
int Numeri::compareto1(T5 num22) {...}
int Numeri::compareto2(Numeri &ptr13_ele14_num24) {...}
//metodi privati
void Numeri::aumenta1(int pos1) {...}
void Numeri::diminuisci1(int pos2) {...}
void Numeri::divisoDieci(int num2) {...}
//metodi grafica
void Numeri::mostra1() {...}
//metodi ritorno campi
int Numeri::getValore1(int pos3) {...}
long double Numeri::getValore2() {...}
string Numeri::getValore3() {...}
E questo e' il Numeri.cpp.
Non so se qualcuno riesce ad aiutarmi. Se non sono stato chiaro o vi servono chiarimenti sul codice sono disponibile. Davvero ho provato con tutto quello che so e cercato ovunque ma non capsico quale possa essere l'errore

p.s.: Cambiando nomi funzioni, variabili, ecc. l'errore rimane uguale. Si risolve se tolgo il template e definisco il tipo.