I have defined class template named CallBackAtInit
which only purpose is to call a function at its initialization (constructor). The function is specified in template parameters. The problem is that templates does not accept std::function
as parameters; but they accept function pointers. Why?
Here is my code:
#include <iostream>
#include <functional>
/* Does not work:*/ template <typename return_type, typename arg_type, std::function<return_type(arg_type)> call_back>
/* Work fine: */// template <typename return_type, typename arg_type, return_type(*call_back)(arg_type)>
class CallBackAtInit {
public:
CallBackAtInit(arg_type arg)
{
call_back(arg);
};
};
void printInt(int i);
class HoldInt : private CallBackAtInit<void, int, printInt> {
public:
HoldInt(int integer)
: CallBackAtInit(integer)
{}
// ...
};
int main(int argc, char** argv)
{
HoldInt hi(10);
return 0;
}
void printInt(int i)
{
std::cout << i << std::endl;
}
No. One is a function pointer; the other is an object that serves as a wrapper around a function pointer. They pretty much represent the same thing, but std::function is far more powerful, allowing you to do make bindings and whatnot.
A template parameter is a special kind of parameter that can be used to pass a type as argument: just like regular function parameters can be used to pass values to a function, template parameters allow to pass also types to a function.
Which parameter is legal for non-type template? Explanation: The following are legal for non-type template parameters:integral or enumeration type, Pointer to object or pointer to function, Reference to object or reference to function, Pointer to member.
Template classes and functions can make use of another kind of template parameter known as a non-type parameter. A template non-type parameter is a template parameter where the type of the parameter is predefined and is substituted for a constexpr value passed in as an argument.
The parameter for a template definition can be of four kinds:
std::nullptr_t
(since C++11)When you mention std::function
in a template definition, then it falls neither of the above categories. The template cannot accept types, nor can it accept integral value, or pointer-to-member value.
When the parameter is function pointer type, then it can accept function-pointer (the address of a function matching the type) which is just an integral value. Note that address is always an integral value. So it falls into the second category, which is why it works.
Because it's not allowed by the standard:
14.1 Template parameters
4 A non-type template-parameter shall have one of the following (optionally cv-qualified) types:
— integral or enumeration type,
— pointer to object or pointer to function,
— lvalue reference to object or lvalue reference to function,
— pointer to member,
— std::nullptr_t.
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