Signatures for functions accepting functions as parameters

Nov 27, 2016 at 9:21pm
std::for_each requires a function that accepts a single parameter of some type and returns void. However, its implementation actually doesn't require a type of std::function to be passed:
1
2
3
4
5
6
7
8
template<class _InIt,
	class _Fn1> inline
	_Fn1 for_each(_InIt _First, _InIt _Last, _Fn1 _Func)
	{	// perform function for each element
	_DEBUG_RANGE_PTR(_First, _Last, _Func);
	_For_each_unchecked(_Unchecked(_First), _Unchecked(_Last), _Func);
	return (_Func);
	}


Notice the _Fn1. It has no constraints and it can accept just about anything. Anything can be passed in, like so:
std::for_each(v.begin(), v.end(), this);

However, I get a compiler error (error C2064: term does not evaluate to a function taking 1 arguments) when trying to compile it, and knowing what for_each does, I understand why. But without further knowledge, until compilation, there is no way to know what kind of function it expects without going deep into the implementation code for for_each.

So I wonder: why didn't they use std::function as a type for the third parameter in std::for_each? Is it because of some limitations of templates? Or is it simply preferable for some other reason?
Last edited on Nov 27, 2016 at 9:26pm
Nov 27, 2016 at 10:18pm
But without further knowledge, until compilation, there is no way to know what kind of function it expects without going deep into the implementation code for for_each.

You could visit the standard or one of the sites that provide documentation, such as this one or http://en.cppreference.com/w/cpp

std::for_each predates std::function.

Nov 28, 2016 at 8:33pm
Thanks. So using using templates to accept functions was the way to go before std::function? Was there any other way for this except function pointers?
Nov 28, 2016 at 9:32pm
Even with std::function, templates are the better way since std::function has runtime overhead which templates avoid.

As for having to check the documentation before calling a library function, highly anticipated C++ language feature "Concepts" will address this. It is already implemented in gcc 6.1, although std::for_each won't be associated with a concept until the Ranges TS joins the C++ standard (or until compilers start implementing it ahead of standardization)

Borrowing the std::for_each definition from the proposal, the error for std::for_each(v.begin(), v.end(), this); becomes

1
2
3
main.cpp:97:43: error: cannot call function 'for_each ...
main.cpp:85:6: note:   constraints not satisfied
main.cpp:85:6: note: in the expansion of concept '(IndirectCallable ...
Topic archived. No new replies allowed.