Sto testando una classe contenuta nei file "Numeri.h" e "Numeri.cpp". Tutte le funzioni non hanno problemi eccetto la funzioneche 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:Numeri divisione1(T4 num18);
Questo e' il main, dove "a" potrebbe anche essere un numero scritto per esteso, anche di tipi differenti.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 Numeri.hcodice:#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
E questo e' il Numeri.cpp.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() {...}
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.



Rispondi quotando
