2009-05-28 5 views
8

w naszym kodzie mamy sporo przypadków tego wzoru:Jaki jest sens tego wzoru: przy użyciu struct zawierać jedną metodę

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

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

Co jest zaletą tego ciągu:

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

    void doThing() 
    { 
     wstring initialValue; 
     wstring finalValue = changeString(initialValue); 
    } 
}; 
+0

dlaczego nie zapytać osoby, która napisała kod? –

+0

, ponieważ nie są dostępne – Ant

+0

Ups. Muszę nauczyć się dokładniej kopiować kod :) – Ant

Odpowiedz

4

Jest to krok optymalizacji dla predykatów na szablony.

Nie chodzi o to, że funktor jest łatwiejszy w użyciu niż funkcja. Oba działają w podobny sposób w kontekstach boost i STL.

Sposób ich odróżnienia polega na tworzeniu szablonu.

Wyobraźmy sobie banalną funkcję szablonu, który wymaga predykat

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

Korzystanie z funkcję będzie instancję instancji szablonu ze wskaźnikiem funkcji.

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*)()); 

Korzystanie z funktor będzie instancję instancji szablonu z typem specyficzny funktora.

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); 

Z funktora, specyficzna funkcjonalność jest teraz dobrze zdefiniowane i struktura są przekazywane w prawdopodobnie nie jest używany i może być zoptymalizowana na zewnątrz.

+1

Bardzo jasne dzięki. – Ant

16

Struktura z operatorem() jest często nazywana funktorem, skutecznie działając jako "obiekt funkcji". Możesz używać tych funktorów z wieloma API, szczególnie STL, łatwiej i bardziej solidnie, niż możesz używać typowych wskaźników funkcyjnych. Funktory będące obiektami, mogą zawierać stan i sparametryzować się podczas budowy, aby stworzyć autonomiczny, specjalistyczny program obsługi.

Podejrzewam, że często razy, masz kod w outerClass, który chce korzystać z tych funkcji bibliotecznych (to jest std :: for_each), i tak rozwinął ten wzór, aby uczynić go banalnym. Jeśli nigdy nie używasz funktorów, to tak, ta składnia jest bez sensu i trudna do odczytania (i może być zastąpiona, jak sugerujesz).

Edytuj: Może Ci się spodobać Question 317450, o operator().

+0

Aha, dzięki czemu ma sens! Myślę, że w niektórych miejscach to z tego powodu, ale w innych jest po prostu kopiowane (wzór, a nie kod). – Ant