2010-03-19 15 views
7

Recientemente he empezado a enseñarme la biblioteca de plantillas estándar. Tenía curiosidad de por qué el método GetTotal() en esta clase está devolviendo 0?functor return 0

... 

class Count 
{ 
public: 
    Count() : total(0){} 
    void operator() (int val){ total += val;} 
    int GetTotal() { return total;} 
private: 
    int total; 
}; 

void main() 
{ 
    set<int> s; 
    Count c; 
    for(int i = 0; i < 10; i++) s.insert(i); 
    for_each(s.begin(), s.end(), c); 
    cout << c.GetTotal() << endl; 
} 

Respuesta

13

for_each toma la función por valor. Es decir, usa una copia del functor y no el propio functor. Su local c no se modifica.

for_each devuelve el funtor que utiliza, sin embargo, por lo que podría hacer:

Count c; 
c = for_each(s.begin(), s.end(), c); 

O más idiomáticamente:

Count c = for_each(s.begin(), s.end(), Count()); 

Sin embargo, existe dicha funcionalidad ya (no es necesario para su funtor) :

int total = std::accumulate(s.begin(), s.end(), 0); 
+1

Eso es contador intuitivo. ¿Sabes por qué lo hicieron de esa manera? –

+0

Es porque c está en la pila y se pasa por valor a for_each, por lo que se pasa una copia de c. No tiene nada que ver con for_each (aparte de que se necesita un funtor en lugar de un puntero a un funtor), sino con la semántica del lenguaje. En cuanto a por qué se necesita un funtor y no un puntero a un funtor podría estar relacionado con que también sea capaz de tomar un puntero a una función, de modo que pase lo que pase, para cada uno puede llamarse f(). Pero esa parte es solo una suposición –

+0

@Mark: No lo sé en realidad. Podrían haberlo hecho una referencia y no debería haber ningún problema. No puedo pensar en una situación en la que ser una referencia me sorprenda tampoco. Tengo curiosidad también. @Brandon: Él no está preguntando qué significa mi respuesta. Quiere decir "¿por qué no lo diseñaron para tomar la función por referencia en lugar de por valor?" :) – GManNickG

Cuestiones relacionadas