Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can std::function be used to store a function with variadic arguments [duplicate]

I have a structure that I pass around my application which contains a bunch of callback functions:

typedef struct {
    std::function<void (void)>    f1;
    std::function<void (int)>     f2;
    std::function<int  (float *)> f3;
    // ... and so on
} CallbackTable;

I handle state control within the application by binding different functions to the various callbacks, depending upon the current system state; it works fine.

What I'd now like to do is to add a couple of extra callbacks with signatures containing variable numbers of arguments, akin to printf: for example,

    std::function<int  (const char * format, ...)> printToStdOut;

This doesn't work. In Visual C++, I get an error message stating:

error C2027: use of undefined type 'std::_Get_function_impl<_Fty>'

I'm still feeling my way through this area of C++ syntax and would very much appreciate any advice on how I should proceed from here. My overriding objective is to be able to make a call along the lines of:

myCallbackTable.printToStdOut("I've just eaten %d bananas\r\n", nBananas);

...and to have the output directed to a console, to a file or to a GUI window, according to the system state.

like image 966
Eos Pengwern Avatar asked Sep 04 '14 17:09

Eos Pengwern


1 Answers

Edit: Original answer was wrong, modified but still may not be a good answer, leaving it here for educational purposes:

Many variable argument functions have a va_list version. printf for example has vprintf. These variants explicitly take a va_list instead of an ellipses.

#include <iostream>
#include <functional>
#include <cstdarg>


int main()
{
   std::function<int(const char*,va_list)> test2(vprintf);

   return 0;
}

Invoking it, however, is a pain.

int invoke_variadic(const std::function<int(const char*,va_list)>& ref,const char* a ,...)
{
    va_list args;
    va_start(args,a);
    ref(a,args);
    va_end(args);
}

What was wrong with original post (thanks /u/T.C.): std::function<int(const char*,va_list)> test2(printf) compiles, which I took to meaning it "worked". However it compiles because printf can accept arguments of any type (including a va_list), and std::function only checks if it can be invoked in that way.

like image 89
IdeaHat Avatar answered Oct 04 '22 21:10

IdeaHat