Search code examples
c++decltypestd-function

Confusion: decltype vs std::function


I am confused a little over the following notation. I want to create a queue, that holds function callbacks. I thought this could be done the following way:

    int fun(int);
    [...]
    std::queue<std::function<int(int)>> q0;
    std::queue<decltype(fun)> q1;
    std::queue<int (int)> q2;

Full code https://onlinegdb.com/rkvAdPpmU

Unfortunately, decltype<fun> and int (int) are not allowed. To be honest, I prefer the std::function way of doing. Now for the next part...

I recently came up with a thing called packaged_task. I tried to define the template the same way as I did with queue:

    int fib(int);
    [...]
    std::packaged_task<int (int)> f0(fib);
    std::packaged_task<decltype(fib)> f1(&fib);
    std::packaged_task<std::function<int(int)>> f2(&fib);

Full code https://www.onlinegdb.com/B17iYvaQL

Compilation yield a different result. Now std::function gave error: variable ‘std::packaged_task<std::function<int(int)> > f2’ has initializer but incomplete type. Other ways of initialization are ok.

My questions:

1) Is int (int) equivalent to decltype(fib), where int fib(int)?

2) While I understand that std::function is actually a templated class, shouldn't it be used the same way in queue and packaged_task?


Solution

  • You cannot store functions, but you can store function pointers:

    std::queue<decltype(&fun)> q1;
    std::queue<int (*)(int)> q2;
    

    Demo

    • decltype(fun) is int (int)
    • decltype(&fun) is int (*)(int)

    std::packaged_task as std::function expects signature,

    so both std::packaged_task<int(int)> and std::packaged_task<decltype(fib)> are ok.

    std::function<int(int)> is a type, not a signature, so std::packaged_task<std::function<int(int)>> is invalid (not defined in fact), so unusable.