Funtore

di il
9 risposte

Funtore

Nel seguente codice non capisco perchè nella chiamata al funtore ComplexComparer() non vengono passate le due istanze a e b della classe Complex infatti dentro la parentesi non c'e' niente.
Se però si guarda la definizione dell'operatore () si nota che prende due oggetti const Complex*.
Forse gli argomenti di ComplexComparer() sono impliciti ?
Ma come vengono determinati?
Sono forse le istanze di classe passate come parametri nella chiamata di max ?
Cioè questi max(a, b, ComplexComparer());



class ComplexComparer
{
public:
	bool operator()(const Complex& a, const Complex& b);
};

bool ComplexComparer::operator()(const Complex& a, const Complex& b)
{
	float magA = std::sqrt(a.getReal() * a.getReal() + a.getIm() * a.getIm());
	float magB = std::sqrt(b.getReal() * b.getReal() + b.getIm() * b.getIm());
	return magA < magB;
}
#include <iostream>
int main()
{
	Complex a(1, 1.5);
	Complex b(0.5f, 4);
	Complex m = std::max(a, b, ComplexComparer());
	std::cout << "max = " << m << std::endl;
	return 0;
}

9 Risposte

  • Re: Funtore

    Devi passargli un'istanza di ComplexComparer.
    
    ComplexComparer comp;
    std::max(a, b, comp);
    
  • Re: Funtore

    Alexv ha scritto:


    Devi passargli un'istanza di ComplexComparer.
    Quello che dici mi torna ma non è così di fatto.
    guarda questo link dove ho letto le informazioni che ho citato https://www.html.it/pag/68390/functor-ridefinizione-delloperatore/

    Inoltre ho anche un altro esempio preso da un testo universitario che dice la tessa cosa per cui ciò che dici non mi convince del tutto.
  • Re: Funtore

    zio_mangrovia ha scritto:



    Quello che dici mi torna ma non è così di fatto.
    guarda questo link dove ho letto le informazioni che ho citato https://www.html.it/pag/68390/functor-ridefinizione-delloperatore/

    Inoltre ho anche un altro esempio preso da un testo universitario che dice la tessa cosa per cui ciò che dici non mi convince del tutto.
    Quando passi ComplexComparer() non stai passando l'operatore (), ma chiami il costruttore di ComplexComparer, che costruisce un oggetto temporaneo e lo passa alla funzione.
  • Re: Funtore

    Alexv ha scritto:


    Quando passi ComplexComparer() non stai passando l'operatore (), ma chiami il costruttore di ComplexComparer, che costruisce un oggetto temporaneo e lo passa alla funzione.
    Benissimo e fin qua tutto ok, ma quando chiami il costruttore di ComplexComparer cosa istanze esattamente in riferimento alla classe ComplexComparer?
    Nella parte privata della classe non c'e' niente, nella parte pubblica invece la ridefinizione dell' operatore ()
    Ma il costruttore istanzia due const Complex& ? Non capisco... l'operatore () pensavo entrasse in gioco solo se gli vengono passati i due parametri ma nel nostro caso non viene passato niente.
  • Re: Funtore

    Alexv ha scritto:


    Quando passi ComplexComparer() non stai passando l'operatore (), ma chiami il costruttore di ComplexComparer, che costruisce un oggetto temporaneo e lo passa alla funzione.
    Benissimo e fin qua tutto ok, ma quando chiami il costruttore di ComplexComparer cosa istanze esattamente in riferimento alla classe ComplexComparer?
    Nella parte privata della classe non c'e' niente, nella parte pubblica invece la ridefinizione dell' operatore ()
    Ma il costruttore istanzia due const Complex& ? Non capisco... l'operatore () pensavo entrasse in gioco solo se gli vengono passati i due parametri ma nel nostro caso non viene passato niente.
  • Re: Funtore

    zio_mangrovia ha scritto:


    Benissimo e fin qua tutto ok, ma quando chiami il costruttore di ComplexComparer cosa istanze esattamente in riferimento alla classe ComplexComparer?
    Nella parte privata della classe non c'e' niente, nella parte pubblica invece la ridefinizione dell' operatore ()
    Ma il costruttore istanzia due const Complex& ? Non capisco... l'operatore () pensavo entrasse in gioco solo se gli vengono passati i due parametri ma nel nostro caso non viene passato niente.
    Il costruttore è una cosa e l'operatore () è un'altra.
    Tutte le classi hanno un costruttore di default se non ne viene dichiarato uno manualmente. La chiamata avviene in un modo simile a quello che ho postato sopra, con la differenza che l'oggetto di tipo ComplexComparer viene copiato nella funzione e "muore" subito dopo. Che cosa viene istanziato? Essendo un oggetto stateless avrà un'occupazione minima in memoria (prova con il sizeof), e se il compilatore è bravo può fare in modo di risparmiare anche quello, ma dal punto di vista del linguaggio un oggetto c'è.

    L'operatore () viene chiamato dalla funzione max, che avrà istruzioni di questo tipo:
    if (comp(a,b)) <fai qualcosa>...
    dove a e b li hai passati tu alla funzione max e a sua volta li passa ComplexComparer::operator() di comp.
  • Re: Funtore

    zio_mangrovia ha scritto:


    guarda questo link dove ho letto le informazioni che ho citato https://www.html.it/pag/68390/functor-ridefinizione-delloperatore/
    Ma che macello viene fatto in quell'articolo?
    Basterebbe questo
    
    #include <iostream>
    using namespace std;
    
    class Complex{
    public:
    	float Re, Im;
    	
    	Complex(float a, float b){
    	    Re = a;
    	    Im = b;
    	}
    	
        	friend ostream& operator <<(ostream& os, const Complex& a){
    	    os << a.Re << " + " << a.Im << "i";
    	    return os;
    	}
        
    	friend bool operator <(const Complex& a, const Complex& b) {
    	    return a.Re * a.Re + a.Im * a.Im < b.Re * b.Re + b.Im * b.Im;
    	}    
    };
    
    int main(){
        Complex a(1,1.5), b(0.5,4);
        cout << "max = " << max(a,b);
        return 0;
    }
    
  • Re: Funtore

    Alexv ha scritto:


    L'operatore () viene chiamato dalla funzione max, che avrà istruzioni di questo tipo:
    if (comp(a,b)) <fai qualcosa>...
    Non vorrei far confusione ma mi piacerebbe aver dei punti fermi su cui riflettere cioè ti riferisci all'operatore () che è definito nella funzione max, spero tu non intenda quello definito nella classe ComplexComparer? Perchè altrimenti significa che non ho capito niente.
    dove a e b li hai passati tu alla funzione max
    perfetto!
    e a sua volta li passa ComplexComparer::operator() di comp.
    Questo scusami ma non lo capisco


    Mi chiedo poi se è lecito passare come 3o argomento di std::max il nome della classe seguita dalle parentesi cioè ComplexComparer() come se venisse invocato il costruttore della classe direttamente.
  • Re: Funtore

    zio_mangrovia ha scritto:


    Non vorrei far confusione ma mi piacerebbe aver dei punti fermi su cui riflettere cioè ti riferisci all'operatore () che è definito nella funzione max, spero tu non intenda quello definito nella classe ComplexComparer? Perchè altrimenti significa che non ho capito niente.
    Ce n'è uno solo ed è quello definito nella classe ComplexComparer. Tu gli passi il comparatore e la funzione usa il suo operatore () per fare i confronti.
    Mi chiedo poi se è lecito passare come 3o argomento di std::max il nome della classe seguita dalle parentesi cioè ComplexComparer() come se venisse invocato il costruttore della classe direttamente.
    È lecito. Ma non gli passi "il costruttore". Prima esegue il costruttore e poi gli passa l'oggetto costruito.
Devi accedere o registrarti per scrivere nel forum
9 risposte