2010-12-14 12 views
7

Mam listę MyClass:Który przypadek jest lepszy?

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

Co przypadek usuwania jest lepszy (C++ projektu i osiągów):

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

lub

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

lub

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

i dlaczego?

P.S. Proszę, nie ma funkcji lambda ani C++ 0x.

Odpowiedz

12

Jeśli chodzi o design, ten, który używa bind jest zdecydowanie najjaśniejszy. (po którym następuje jawny obiekt funkcji). Czemu? Zwięzły.

Pod względem wydajności obiekt funkcji powinien być nie do pobicia (wszystko można łatwo przeanalizować i zaznaczyć). W zależności od tego, jak optymalizuje się kompilator, ten, który używa bind, może go dopasować (wywołanie do is_old_result może, ale nie musi, za pośrednictwem wskaźnika, w zależności od analizy kompilatora).

+0

Zgadzam się całkowicie. – ltjax

+0

Zgadzam się również, składnia wiązania jest najłatwiejsza do odczytania. Jeśli wydajność jest kwestią drugorzędną, przejdź do binda tutaj. –

+3

Zgadzam się również, a dodam, że wydajność powinna stanowić problem wtórny, chyba że/dopóki profilowanie i stwierdzenie, że to stwierdzenie nie jest wąskim gardłem wydajności. –

3

z bardziej odpowiedniego nazw, takich jak „IsOldResult” lub „ResultOlderThan” by powiedzieć, że ostateczne rozwiązanie byłoby najbardziej czytelne, ponieważ jest to ten, który najbardziej przechodzi do proza:

results.remove_if(ResultOlderThan(lifetime)); 

Jednak prawdopodobnie poszedłbym i zapisał funktora, gdyby reprezentowany przez niego algorytm pojawił się w wielu kontekstach. Napisanie pięcioliniowej klasy fizycznie usuniętej z pojedynczej witryny z jednym linkiem wydaje mi się zbyt nieefektywne.

W przeciwnym razie opcja boost :: bind ma mój głos, ponieważ ma najmniejszy dodatkowy fluff między nim a std :: bind2nd (odpowiednio _1 i std :: mem_fun_ref). Ponadto boost :: bind działa w większej liczbie przypadków, na przykład w przypadku, gdy nie wiążesz tylko jednej zmiennej funkcji, która ma tylko dwa parametry.

+0

dobry punkt o odpowiednim 'ResultOlderThan' –

Powiązane problemy