如何将`void(* fn)(const char *,...)`转换为`std :: function`,反之亦然

Zak*_*Zak 5 c++ lambda function variadic-functions

typedef void(*fn1)(const char *, ...);
typedef std::function<void(const char *, ...)> fn2; // has initializer but incomplete type
Run Code Online (Sandbox Code Playgroud)

直觉上,这些对我来说实际上是相同的,但显然我的直觉使我失望。我将如何协调这些数据类型?

  1. fn2不完整的类型如何?
  2. fn2为了使我能够为其分配类型,需要对它们的签名进行哪些更改fn1
  3. 创建要分配给的lambda时fn2,如何访问可变参数列表?

    换句话说,lambda等于以下什么?

    void fn1_compatible (const char * format, ...) {
      va_list args;
      va_start(args, format);
      //TODO: Do stuff with variadic arguments
      va_end(args);
    }
    
    Run Code Online (Sandbox Code Playgroud)

注意:顺便说一句,这些签名与日志记录有关,但是请在常规(而非日志记录)上下文中回答该问题。

eer*_*ika 2

据我所知,你不能。

如果你能稍微改变一下你的前提。那是; printf您可以使用 ,而不是使用 example vprintf。那么你可以:

using fn2 = std::function<int(const char*, va_list)>;
fn2 fun = vprintf;
Run Code Online (Sandbox Code Playgroud)

然后,您可以提供一个包装函数来调用fn2...参数的 a:

int fun_wrapper(const char *format, ...) {
    va_list args;
    va_start(args, format);
    int ret = fun(format, args);
    va_end(args);
    return ret;
}
Run Code Online (Sandbox Code Playgroud)

通常, ...函数只是包含va_list实际实现的替代方案的包装器。就像所示的fun_wrapper 是 的包装器一样fun

但是,如果...您要使用的函数没有va_list列表版本,并且不是由您实现的,那么您最好的选择可能是使用其他函数。