Why does std::for_each return the Functor ?


In short: Because the provided Functor is copied by for_each.

A bit longer:

  • the functor has to be copied so that for_each can use a reference to it in the loopage
  • as the functor is copied, the context of the functor would be lost at end of for_each if it was not returned
class Object {
public:
    int getValue() const;
};
class Accumulator {
public:
    Accumulator() : _sum(0) { }
    void operator()(const Object &o) {
        _sum += o.getValue();
    }
    int getSum() const {
        return _sum;
    }
 
private:
    int _sum;
};
void showSum(std::vector<Object> v) {
    Accumulator result = std::for_each(v.begin(), v.end(), Accumulator());
    std::cout << result.getSum() << std::endl;
}

If std::for_each was taking a reference to the given Accumulator, it would be impossible to provide a temporary object as is done here. The drawback of this is that the three functor object will be created (temporary, copied for parameter by value, copied for return value by value).

As the functor is copied, code like this will not work:

void badCalculateSum(std::vector<Object> v) {
    Accumulator result;
    std::for_each(v.begin(), v.end(), result);
    std::cout << result.getSum() << std::endl; // will print 0 !
}
Share

,

  1. #1 by Christophe on 8 février 2014 - 13:57

    In badCalculateSum, passing std::ref(result) instead of result solves the issue.

Les commentaires sont fermés.