Visualizzazione dei risultati da 1 a 10 su 10
  1. #1

    [C++] Problema puntatore a funzione membro

    Ho una classe del tipo:

    codice:
    class prova
    {
    	bool compare( int i, int j )
    	{
    		return i < j;
    	}
    
    	void sort_vect()
    	{
    		std::sort( vect.begin(), vect.end(), compare );
    	}
    
    	vector <int> vect;
    };

    Ho il relativo errore di compilazione: chiamata di funzione senza elenco di argomenti; utilizzare 'prova::compare' per creare un puntatore al membro.

    Risolvo dichiarando compare funzione globale. Perchè? Soluzioni diverse?
    Fracty - The Fractal Generator



    If you cannot choose a concise name that expresses what the method does, it is possible that your method is attempting to perform too many diverse tasks.

  2. #2

    Re: [C++] Problema puntatore a funzione membro

    Originariamente inviato da GliderKite
    Soluzioni diverse?
    Codice PHP:
    #include <iostream>
    #include <functional>
    #include <algorithm>
    #include <vector>
    #include <iterator>

    namespace ig{
        
    template <typename TFunctortypename TObject>
        class 
    GWrapper{
            public:
            
    bool operator () (const int i, const int j) const{
                return (
    fObject.*fFunctor) (ij);
            }
            private:
            
    TFunctor fFunctor;
            const 
    TObject &fObject;
        
            public:
            
    GWrapper (TFunctor theFunctorTObject theObject):
            
    fFunctor (theFunctor),
            
    fObject (theObject){
            }
        };
    }

    class 
    prova
    {
        public:
        
    bool compare( const int i, const int j) const
        {
            return 
    j;
        }
                
        
    void sort_vect()
        {
        
    typedef bool (prova::* MemFunPtr)(const int, const int) const;
        
    ig::GWrapper <MemFunPtrprovaaWrapper (&prova::compare, *this);  
            
    std::sortvect.begin(), vect.end(), aWrapper);
        }
        
    std::vector <intvect;
    };

    int main (void){
    /*
    $ g++ --version
    g++ (GCC) 4.1.2 20080704 (Red Hat 4.1.2-48)

    $ g++ -Wall -Wextra -Wconversion -pedantic -ansi main.cpp

    $ ./a.out
    original:
    1, 3, 2, 4,
    sorted:
    1, 2, 3, 4,
    bye bye...

    */
        
    prova aProva;
        
    aProva.vect.push_back (1);
        
    aProva.vect.push_back (3);
        
    aProva.vect.push_back (2);
        
    aProva.vect.push_back (4);
        
    std::cout << "original: " << std::endl;
        
    std::copy (aProva.vect.begin (), aProva.vect.end (), std::ostream_iterator <int>(std::cout", "));
        
    std::cout << std::endl;
        
    std::cout << "sorted: " << std::endl;
        
    aProva.sort_vect ();
        
    std::copy (aProva.vect.begin (), aProva.vect.end (), std::ostream_iterator <int>(std::cout", "));
        
    std::cout << std::endl;
        
    std::cout << "bye bye..." << std::endl;
        return 
    0;


  3. #3
    Quindi tu consiglieresti l'utilizzo di un funtore piuttosto che un puntatore a funzione globale? Perchè?

    Io l'avrei fatta più semplice, probabilmente una cosa del tipo:

    codice:
    template <typename T>
    struct cmp
    {
    	inline bool operator()( const T i, const T j ) const
    	{
    		return i < j;
    	}
    };

    Perchè includere functional?

    Visto che si tratta di una funzione di ordinamento (std::sort) si presume si ricerchi la maggior efficienza possibile, l'utilizzo di un funtore risulta più efficiente?

    Grazie
    Fracty - The Fractal Generator



    If you cannot choose a concise name that expresses what the method does, it is possible that your method is attempting to perform too many diverse tasks.

  4. #4
    Non puoi creare un puntatore a funzione relativo ad una specifica istanza di una funzione membro: un puntatore a funzione, infatti, è semplicemente un indirizzo, mentre un puntatore ad una funzione di un'istanza sono l'indirizzo della funzione e l'indirizzo dell'oggetto su cui viene dichiarata. Boost se non erro fornisce qualche magia per creare automaticamente functori dalla coppia istanza-puntatore a membro.
    Originariamente inviato da GliderKite
    Visto che si tratta di una funzione di ordinamento (std::sort) si presume si ricerchi la maggior efficienza possibile, l'utilizzo di un funtore risulta più efficiente?
    In functori inline sono in genere più efficienti, dato che un puntatore a funzione richiede sempre una CALL via puntatore, mentre con i functori in genere il compilatore ha tutto ciò che gli serve per effettuare l'inlining della funzione di confronto. Questo è il motivo per cui std::sort con un functore come operatore di confronto batte quasi sempre qsort con puntatore a funzione in termini di efficienza.
    Amaro C++, il gusto pieno dell'undefined behavior.

  5. #5
    Originariamente inviato da MItaly
    un puntatore ad una funzione di un'istanza sono l'indirizzo della funzione e l'indirizzo dell'oggetto su cui viene dichiarata.

    Quella congiunzione che significato ha esattamente?


    Originariamente inviato da MItaly
    Boost se non erro fornisce qualche magia per creare automaticamente functori dalla coppia istanza-puntatore a membro.
    Sai anche dove cercare per avere più informazioni?
    Fracty - The Fractal Generator



    If you cannot choose a concise name that expresses what the method does, it is possible that your method is attempting to perform too many diverse tasks.

  6. #6
    Originariamente inviato da GliderKite
    Quella congiunzione che significato ha esattamente?
    Vedila in un'altra maniera: se vuoi richiamare una funzione normale, tutto ciò di cui hai bisogno è il suo indirizzo in memoria e la sua firma (parametri, valore restituito, eccetera). La firma è risolta a compile time nelle istruzioni usate per chiamarla, l'indirizzo è ciò che viene memorizzato in un puntatore a funzione.

    Se invece vuoi richiamare una funzione membro, hai bisogno, oltre che di sapere dove si trova in memoria, anche dell'istanza su cui la stai richiamando, ossia del puntatore this che le verrà passato. Dato che si tratta complessivamente di due puntatori, un normale puntatore a funzione non basta.
    Sai anche dove cercare per avere più informazioni?
    Boost.Function + Boost.Bind (esempio), credo si possa anche usare Boost.Signal
    Va detto che nel nuovo standard C++ l'intera questione si può risolvere facilmente con una lambda function.
    Amaro C++, il gusto pieno dell'undefined behavior.

  7. #7
    Originariamente inviato da MItaly
    Boost.Function + Boost.Bind (esempio), credo si possa anche usare Boost.Signal
    Va detto che nel nuovo standard C++ l'intera questione si può risolvere facilmente con una lambda function.
    Perfetto, e visto che è saltato fuori l'argomento: dove posso trovare una buona e completa documentazione (per quanto possibile) sul nuovo standard C++?
    Fracty - The Fractal Generator



    If you cannot choose a concise name that expresses what the method does, it is possible that your method is attempting to perform too many diverse tasks.

  8. #8
    Originariamente inviato da GliderKite
    Perfetto, e visto che è saltato fuori l'argomento: dove posso trovare una buona e completa documentazione (per quanto possibile) sul nuovo standard C++?
    Io inizierei con un'occhiata alla relativa pagina sulla Wikipedia. Tra le feature che attendo di più: le lambda functions , le keyword auto e decltype.
    Amaro C++, il gusto pieno dell'undefined behavior.

  9. #9
    Originariamente inviato da MItaly
    Io inizierei con un'occhiata alla relativa pagina sulla Wikipedia. Tra le feature che attendo di più: le lambda functions , le keyword auto e decltype.
    Si su wikipedia mi ero già documentato, un altro link interessante sull'argomento è questo. Mi chiedevo se ci fosse qualcosa di più didattico e completo.
    Fracty - The Fractal Generator



    If you cannot choose a concise name that expresses what the method does, it is possible that your method is attempting to perform too many diverse tasks.

  10. #10
    Originariamente inviato da GliderKite
    Quindi tu consiglieresti l'utilizzo di un funtore piuttosto che un puntatore a funzione globale?
    No, non è detto; ho proposto una soluzione alternativa a quella di una funzione globale, come tu avevi appunto richiesto.
    Originariamente inviato da GliderKite
    Perchè includere functional?
    Traccia del tentativo di utilizzare la comodissima std::mem_fun, ma purtroppo funziona solo se la funzione membro da puntare, ha al max 1 argomento.

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.