Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 11
  1. #1
    Utente bannato
    Registrato dal
    Oct 2010
    Messaggi
    1,219

    [c++]pila di char e di int

    Come fare per creare una pila che abbia come tipo sia un char che un int?
    Vorrei fare una cosa del genere:
    codice:
    stack <int,char> s;
    Ma mi da errore di sintassi.

  2. #2
    Intendi memorizzare una coppia char-int come elemento dello stack? Puoi usare come argomento template una struct ad-hoc, una struttura std:air<char, int> o (in C++11) una std::tuple<char, int>.
    Amaro C++, il gusto pieno dell'undefined behavior.

  3. #3
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,462
    Usa una struttura con un int e un char
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  4. #4
    Utente bannato
    Registrato dal
    Oct 2010
    Messaggi
    1,219
    Non una coppia int char, mi serve proprio una pila che contiene sia int che char, ma in maniera separata.Ad esempio il primo elemento è 'c', il secondo è 5, il terzo 3 ...
    In java lo farei creando un ArrayList<Object> e ci pusherei dei Character e degli Integer, come farlo in c++ ?

  5. #5
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,462
    Beh, un char è (in prima approssimazione) un int ... che differenza c'è?

    Il primo elemento è

    'c' oppure (int)'c'

    il secondo è

    5 oppure (char)5
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  6. #6
    Se però vuoi mantenere l'informazione del tipo iniziale puoi usare il metodo "classico" C per gestire queste situazioni: struct+union+enum, condendola con un goccio di C++ per renderla più comoda:
    codice:
    #include <stack>
    #include <iostream>
    #include <stdexcept>
    
    using std::cout;
    
    // L'elemento da mettere nella lista
    struct Elem
    {
        // Una union condivide la memoria tra due elementi
        // Di fatto significa che puoi leggere solo dall'ultimo che hai scritto se vuoi avere risultati sensati
        // Qui memorizziamo i dati
        union
        {
            char c;
            int i;
        } u;
        // Qui invece memorizziamo il tipo effettivamente registrato in u
        enum
        {
            elemChar,
            elemInt
        } type;
        
        // Costruttori per rendere comodo l'uso della struct
        Elem(char c) : type(elemChar)
        {
            u.c=c;
        }
    
        Elem(int i) : type(elemInt)
        {
            u.i=i;
        }
    
        // Operatori di conversione implicita ai tipi desiderati
        operator int() const
        {
            if(type!=elemInt)
                throw std::logic_error("Questo elemento non contiene un int.");
            return u.i;
        }
    
        operator char() const
        {
            if(type!=elemChar)
                throw std::logic_error("Questo elemento non contiene un char.");
            return u.i;
        }
    };
    
    // Operatore di scrittura su stream per comodità
    std::ostream & operator<<(std::ostream & os, const Elem & right)
    {
         if(right.type==Elem::elemInt)
            os<<(int)right;
        else
            os<<(char)right;
    }
    
    int main()
    {
        std::stack<Elem> stack;
        stack.push('a');
        stack.push(1);
        int i = stack.top(); // memorizza 1 in i (estrae l'int grazie al cast implicito - per sicurezza può essere meglio usare un cast esplicito in casi ambigui)
        cout<<"Ho estratto: "<<i<<"\n";
        stack.pop();
        cout<<"Ora scrivo l'altro elemento direttamente sullo stream: "<<stack.top()<<"\n"; // stampa a grazie all'operatore in overload
        try
        {
            // Prova a prendere un char e un int da un elemento che in realtà contiene un char
            char c = stack.top();
            cout<<"char estratto senza problemi!\n";
            int i = stack.top();
            cout<<"int estratto senza problemi!\n";
        }
        catch(std::exception & ex)
        {
            cout<<"Catturata eccezione: "<<ex.what()<<"\n";
        }
        return 0;
    }
    (lo vedi in azione direttamente qui)

    L'alternativa, per non stare a reinventare la ruota ogni volta, può essere usare boost::variant (che va bene per casi come questo in cui i tipi da memorizzare sono determinati in maniera fissa)
    codice:
    #include <stack>
    #include <iostream>
    #include <boost/variant.hpp>
     
    using std::cout;
     
    int main()
    {
        std::stack<boost::variant<char, int> > stack;
        stack.push('a');
        stack.push(1);
        int i = boost::get<int>(stack.top()); // memorizza 1 in i
        cout<<"Ho estratto: "<<i<<"\n";
        stack.pop();
        cout<<"Ora scrivo l'altro elemento direttamente sullo stream: "<<stack.top()<<"\n"; // stampa a grazie all'operatore in overload
        try
        {
            // Prova a prendere un char e un int da un elemento che in realtà contiene un char
            char c = boost::get<char>(stack.top());
            cout<<"char estratto senza problemi!\n";
            int i = boost::get<int>(stack.top());
            cout<<"int estratto senza problemi!\n";
        }
        catch(std::exception & ex)
        {
            cout<<"Catturata eccezione: "<<ex.what()<<"\n";
        }
        return 0;
    }
    (link)

    Vale la pena di sapere che esiste anche boost::any se devi poter memorizzare qualunque valore.
    Amaro C++, il gusto pieno dell'undefined behavior.

  7. #7
    Utente bannato
    Registrato dal
    Oct 2010
    Messaggi
    1,219
    Il problema dell' usare un char come se fosse un int è proprio che quando estraggo un elemento dalla pila voglio anche sapere di che tipo è.Dovrei creare una struttura con anche un campo che ti dice il tipo della variabile.
    Ho provato la soluzione con boost/variant, ma non mi trova boost/variant.hpp ,sto usando code::blocks con gcc.
    Cosa devo aggiungere nelle opzioni al compilatore?

  8. #8
    Probabilmente devi solo installare boost.
    Amaro C++, il gusto pieno dell'undefined behavior.

  9. #9
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,462
    Ti servono tutti i 32 bit dell'intero? Altrimenti uno lo potresti riservare al tipo ...
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  10. #10
    Utente bannato
    Registrato dal
    Oct 2010
    Messaggi
    1,219
    Si potrebbero servirmi tutti.Il programma deve essere lo scanner di una calcolatrice, si potrebbero inserire anche valori altissimi.
    Ho scaricato boost, e nella directory variant ho tutti gli header che mi servono, tra cui boost/variant.hpp.Come si fa con gcc a dirgli in che directory guardare per cercare gli header?

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 © 2024 vBulletin Solutions, Inc. All rights reserved.