Ho trovato alcuni buoni esempi di functor su SO come this uno, e tutti gli esempi convincenti sembrano utilizzare lo stato nella classe che definisce operator()
.Motivo per utilizzare questa classe stateless con una funzione call operator vs una funzione di stile c?
Mi sono imbattuto in un esempio in un libro che definisce l'operatore di chiamata di funzione senza stato, e non posso fare a meno di sentire che questo è un uso scomodo e che un normale puntatore a funzione di stile sarebbe meglio dell'uso operator()
in ogni modo qui: meno codice, meno variabili (devi istanziare i comparatori), è probabilmente più efficiente a causa dell'istanza e senza perdita di significato o incapsulamento (dato che è solo una funzione).
Lo so std::sort
consente di scegliere tra operator()
classi e funzioni, ma ho sempre utilizzato le funzioni solo a causa della logica di cui sopra.
Quali sono i motivi per cui una classe potrebbe essere preferita?
Ecco l'esempio (parafrasato):
class Point2D {
//.. accessors, constructors
int x,y;
};
class HorizComp {
public:
bool operator()(const Point2D& p, const Point2D& q) const
{ return p.getX() < q.getX(); }
};
class VertComp {
public:
bool operator()(const Point2D& p, const Point2D& q) const
{ return p.getY() < q.getY(); }
};
template <typename E, typename C>
void printSmaller(const E& p, const E& q, const C& isLess) {
cout << (isLess(p, q) ? p : q) << endl; // print the smaller of p and q
}
//...
// usage in some function:
Point2D p(1.2, 3.2), q(1.5, 9.2);
HorizComp horizComp;
VertComp vorizComp;
printSmaller(p, q, horizComp);
printSmaller(p, q, vorizComp);
freddo, non ho pensato a tale proposito. Ho trovato un post sul blog che mostra il rendimento in linea in azione: http://codeforthought.blogspot.com/2011/07/performance-functors-vs-functions.html –
Devo ammettere che vedo questo come un problema del compilatore. Ho visto problemi simili con inlining e il compilatore non è riuscito a de-virtualizzare le chiamate come risultato. Mi sembra che questo sia qualcosa che dovrebbe essere raggiunto da una costante propagazione ottimizzata (a patto che in questo caso sia visibile la definizione di 'less_than'). –
@MatthieuM .: È sicuramente un problema con il compilatore. Ecco perché ho usato i termini "più difficile", "più facile", ecc. Non c'è una ragione fondamentale per cui il compilatore * non * genera istanze separate per entrambi i predicati come funzioni e ancora in linea i loro corpi. È solo che, per ragioni pratiche, gli implementatori del compilatore potrebbero non aver (ancora) fatto un caso speciale per questa situazione. –