Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why isn't std::function a valid template parameter while a function pointer is?

Tags:

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;
}
like image 900
Leonardo Raele Avatar asked Dec 01 '12 16:12

Leonardo Raele


People also ask

Is std :: function a function pointer?

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.

Can a template parameter be a function?

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 C++?

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.

Can we pass Nontype parameters to templates?

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.


2 Answers

The parameter for a template definition can be of four kinds:

  • parameter which can accept only type (or template type).
  • parameter which can accept only integral value.
  • parameter which can accept only pointer-to-member value.
  • 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.

like image 139
Nawaz Avatar answered Sep 23 '22 14:09

Nawaz


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.

like image 39
chill Avatar answered Sep 21 '22 14:09

chill