Hva er poenget med dette mønsteret: ved hjelp av en struct å inneholde en enkelt metode

stemmer
8

I vår kode har vi ganske mange tilfeller av dette mønsteret:

class outerClass
{
    struct innerStruct
    {
        wstring operator()( wstring value )
        {
            //do something
            return value;
        }
    };

    void doThing()
    {
        wstring initialValue;
        wstring finalValue = innerStruct()( initialValue );
    }
};

Hva er fordelen med dette over:

class outerClass
{
    wstring changeString( wstring value )
    {
        //do something
        return value;
    }

    void doThing()
    {
        wstring initialValue;
        wstring finalValue = changeString( initialValue );
    }
};
Publisert på 28/05/2009 klokken 16:20
kilden bruker
På andre språk...                            


2 svar

stemmer
16

En struct med en operatør () er ofte kalt en funktor, som effektivt virker som en "Function objekt". Du kan bruke disse funktorer med mange APIer, spesielt STL, lettere og robust enn du kan bruke vanlige funksjonspekere. Funktorer blir objekter, kan de inneholde tilstand, og bli parametriseres under konstruksjon for å skape en selvstendig spesialisert behandleren.

Jeg antar at ofte har du kode i outerClass som ønsker å bruke disse biblioteksfunksjoner (dvs. std :: for_each), og så har utviklet dette mønsteret for å gjøre det trivielt. Hvis du aldri bruker funktorer, så ja, dette er syntaks meningsløst og vanskelig å lese (og kan bli erstattet som du foreslår).

Edit: Kanskje du har lyst Spørsmål 317450 , om operator ().

Svarte 28/05/2009 kl. 16:22
kilden bruker

stemmer
4

Det er en optimalisering skritt for malbasert predikater.

Det er ikke et spørsmål om en funktor være enklere å bruke enn en funksjon. Begge fungerer ganske mye på samme måte i boost og STL sammenhenger.

Hvordan de skiller er i malen oppretting.

Tenk deg en triviell mal funksjon som krever et predikat

template< typename Predicate >
void  DoSomething( Predicate func )
{
  func();
}

Ved hjelp av en funksjon vil instansiere en mal for eksempel med en funksjon peker .

void changeString();

DoSomething( &changeString );

// This creates a template instantiation expecting a pointer to a function.
// The specific pointer may be evaluated at runtime.

// void DoSomething( void(func*)() );

Ved hjelp av en funktor vil instansiere en mal for eksempel med en spesifikk funktor typen .

struct changeString
{
    void operator() ();
}

DoSomething( changeString() );

// This creates a template instantiation expecting an instance of the struct.
// The exact function being called is now known at compile time.

// void DoSomething( changeString );

Med funktor er den spesifikke funksjonaliteten nå godt definert og struct som sendes inn er sannsynligvis ikke brukt og kan optimaliseres ut.

Svarte 28/05/2009 kl. 18:17
kilden bruker

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more