2010-12-14 11 views
7

tengo una lista de MyClass:¿Qué caso es mejor?

struct MyClass { 
    bool is_old_result(int lifetime); 
}; 
std::list<MyClass> results; 
int lifetime = 50; // or something else 

Qué caso de la eliminación es mejor (C++ diseño y perfomance de):

results.remove_if(
    std::bind2nd(std::mem_fun_ref(&MyClass::is_old_result), lifetime)); 

o

results.remove_if(boost::bind(&MyClass::is_old_result, _1, lifetime)); 

o

struct RemoveFunctor { 
    RemoveFunctor (int lifetime) : lifetime(lifetime) {} 
    bool operator()(const MyClass & m) { return m.is_old_result(lifetime); } 
private: 
    int lifetime; 
}; 
results.remove_if(RemoveFunctor(lifetime)); 

y por qué?

P.S. Por favor, no hay función lambda ni C++ 0x.

Respuesta

12

En términos de diseño, el que usa bind es definitivamente el más claro. (seguido por el objeto de función explícito). ¿Por qué? Sucinto.

En términos de rendimiento, el objeto de función debe ser inmejorable (todo puede analizarse fácilmente y estar en línea). Dependiendo de cómo se optimice el compilador, el que usa bind podría coincidir con él (la llamada a is_old_result puede o no ser a través de un puntero, según el análisis del compilador).

+0

Estoy completamente de acuerdo. – ltjax

+0

Estoy de acuerdo, la sintaxis de enlace es la más fácil de leer. Si el rendimiento es una preocupación secundaria, dirígete aquí. –

+3

También estoy de acuerdo, y agregaré que el rendimiento debería ser una preocupación secundaria a menos que/hasta que hayas perfilado y determinado que esta declaración es un cuello de botella de rendimiento. –

3

Con denominación más adecuada, tal como "IsOldResult" o "ResultOlderThan", yo diría que la solución final sería la más fácil de leer, ya que es el que más pases para la prosa:

results.remove_if(ResultOlderThan(lifetime)); 

Sin embargo, probablemente solo vaya y escriba el funtor si el algoritmo que representa aparece en múltiples contextos. Escribir una clase de 5 líneas que se elimina físicamente de su sitio único de una sola línea me parece demasiado derrochador.

De lo contrario, la opción boost :: bind tiene mi voto, ya que tiene la menor pelusa adicional entre él y std :: bind2nd (_1 y std :: mem_fun_ref, respectivamente). Además, boost :: bind funciona para más casos en general, como un caso en el que no se vincula solo una variable de una función que tiene solo dos parámetros.

+0

es un buen punto acerca de "ResultOlderThan" adecuado –