Visualizzazione dei risultati da 1 a 1 su 1
  1. #1
    Utente di HTML.it L'avatar di Michi19
    Registrato dal
    Mar 2023
    residenza
    Bergamo
    Messaggi
    0

    [C++] Errore "undefined reference" con funzioni template

    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.
    Ultima modifica di Michi19; 16-03-2023 a 16:23

Tag per questa discussione

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.