0

Every time I see function taking function as template parameter, it takes function object by value.

E.g. from for_each reference

template<class InputIterator, class Function>
  Function for_each(InputIterator first, InputIterator last, Function fn)
{
  while (first!=last) {
    fn (*first);
    ++first;
  }
  return fn;      // or, since C++11: return move(fn);
}

1) Why is that?

There are many things you can pass inside, raw function, lambda function, std::function, functor... So object can be quite large (especially std::function or custom functor) and passing by value is not ideal. But reference says, that fn must be function pointer or a move constructible function object.

struct FunctorNMC //non-move-constructible
{
    FunctorNMC() = default;
    FunctorNMC(FunctorNMC&&) = delete;

    void operator()(int a) const { std::cout << a << " ";   }
};

cannot call like:

std::vector<int> v{1,2,3};
for_each(v.begin(), v.end(), FunctorNMC());

in VS2013 can be called like:

FunctorNMC tmp;
my_for_each(v.begin(), v.end(), tmp);

but IDEONE gives error.

2) Why is that? What if I have functor, which for some reason don't support move?

3) Shouldn't be function taken as something like Function && fn?

4) Can be function object passed by value (without moving)?

IDEONE project to play around if needed.

relaxxx
  • 7,566
  • 8
  • 37
  • 64
  • 2
    That code fails to compile because explicitly declaring a move constructor causes the implicitly defined copy constructor to be deleted. If you supply a copy constructor then it should work. Anyway, I'm having a hard time seeing why you would ever want to make a functor that can be neither copied nor moved. – Brian Bi Apr 23 '14 at 20:25
  • 2
    See http://stackoverflow.com/a/5481588/3537339 – Bruno Ferreira Apr 23 '14 at 20:26
  • Possible duplicate of [What does T&& (double ampersand) mean in C++11?](http://stackoverflow.com/questions/5481539/what-does-t-double-ampersand-mean-in-c11) – Paul Sweatte Apr 19 '17 at 14:19

0 Answers0