2009-05-28 6 views
8

En nuestro código tenemos un buen número de casos de este patrón:Cuál es el punto de este patrón: el uso de una estructura para contener un único método

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

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

¿Cuál es la ventaja de este sobre: ​​

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

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

¿por qué no preguntarle a la persona que escribió el código? –

+0

porque no están disponibles – Ant

+0

Vaya. Debe aprender a copiar el código con más cuidado :) – Ant

Respuesta

4

Es un paso de optimización para predicados con plantilla.

No se trata de un functor que sea más fácil de usar que una función. Ambos funcionan más o menos de la misma manera en los contextos boost y STL.

Cómo difieren en la creación de instancias de plantillas.

imaginar una función de plantilla trivial que requiere un predicado

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

Utilizando una funciónva a crear una instancia de plantilla con un puntero función.

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

El uso de un funtor se instanciar una instancia de plantilla con un tipo funtor específica.

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

Con el funtor, la funcionalidad específica está ahora bien definido y el struct que se pasa en es probable no se utiliza y se puede optimizar a cabo.

+1

Muy claro gracias. – Ant

16

Una estructura con un operador() a menudo se denomina un funtor, que actúa eficazmente como un "objeto de función". Puede usar estos funtores con muchas API, especialmente el STL, de forma más fácil y sólida que con los punteros de función típicos. Los funtores son objetos, pueden contener estado y se pueden parametrizar durante la construcción para crear un manejador especializado autónomo.

Supongo que muchas veces, tiene un código en outerClass que quiere usar estas funciones de la biblioteca (es decir, std :: for_each), por lo que ha desarrollado este patrón para hacerlo trivial. Si nunca usas funtores, entonces sí, esta sintaxis no tiene sentido y es difícil de leer (y puede ser reemplazada como sugieras).

Editar: Puede que le guste Question 317450, sobre el operador().

+0

Aha que tiene sentido gracias! Creo que en algunos lugares es por esa razón, pero en otros simplemente se ha copiado (el patrón, no el código). – Ant

Cuestiones relacionadas