I am trying to pass a pointer to the predicate function into the Foo
and Bar
functions.
The Bar
function works correctly, but the Foo
function raises a compile-time error:
error: no matching function for call to
Foo<int>(bool (&)(int))
Why does the compiler raise an error?
Is there any difference between Foo
's and Bar
's template arguments types after Args
' unpacking?
#include <functional>
bool predicate(int a) {
return (a > 5);
}
// sizeof...(Args) == 1 and I suppose it is int
template<typename... Args>
void Foo(std::function<bool(Args...)> predicate) {
// clang: note: candidate template ignored:
// could not match 'function<bool (int, type-parameter-0-0...)>'
// against 'bool (*)(int)'
}
template<typename Args>
void Bar(std::function<bool(Args)> predicate) {
}
int main(int argc, char const *argv[]) {
// gcc: error: no matching function for call to
// 'Foo<int>(bool (&)(int))'
Foo<int>(predicate);
Bar<int>(predicate);
return 0;
}
See Compiler Explorer for a live example.
I also tried to change the Foo
function a little and it works somehow:
template<typename... Args>
void Foo(bool(*predicate)(Args...)) {
std::function<bool(Args...)> func(predicate);
}
I want to have std::function
type argument in the Foo
function, but I don't know how to do it
Function Call When calling a function with a function parameter, the value passed must be a pointer to a function. Use the function's name (without parentheses) for this: func(print); would call func , passing the print function to it.
We cannot pass the function as an argument to another function. But we can pass the reference of a function as a parameter by using a function pointer. This process is known as call by reference as the function parameter is passed as a pointer that holds the address of arguments.
So when calling a function template, there is no need to explictly pass the arguments, on the contrary, it can do harm! Consider the example I gave right at the start: We have reference parameters, so case two described above. This means that the type of the template argument will be the same as the type of the argument without references.
Function pointers can be passed as template parameters, and this is part of standard C++ . However in the template they are declared and used as functions rather than pointer-to-function. At template instantiation one passes the address of the function rather than just the name.
Because functions are objects we can pass them as arguments to other functions. Functions that can accept other functions as arguments are also called higher-order functions. In the example below, a function greet is created which takes a function as an argument. greeting = func ("Hi, I am created by a function passed as an argument.")
A function can also be passed to another function by passing its address to that function. Below is the C++ program to illustrate the same: In C++ 11, there is a std::function<> template class that allows to pass functions as objects. An object of std::function<> can be created as follows.
The error is because the exact type of std::function
is not same as predicate
. To get around this, you can explicitly call the constructor of std::function
:
int main() {
Foo<int>( std::function<bool(int){predicate} );
//OR
Foo<int>( {predicate} );
return 0;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With