Signatures for functions accepting functions as parameters

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
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.

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?
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.