如何将`void(* fn)(const char *,...)`转换为`std :: function`,反之亦然 [英] How to translate `void(*fn)(const char *, ...)` to `std::function` and vice versa

查看:184
本文介绍了如何将`void(* fn)(const char *,...)`转换为`std :: function`,反之亦然的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

Intuitively, these are the effectively the same to me, but obviously my intuition is failing me. How would I reconcile these data types?

  1. fn2如何是不完整的类型?
  2. fn2的签名需要进行哪些更改,才能为我指定fn1类型?
  3. 在创建要分配给fn2的lambda时,如何访问可变参数列表?

  1. How is fn2 an incomplete type?
  2. What changes are necessary to the signature of fn2, to allow me to assign it a type of fn1?
  3. When creating a lambda to assign to fn2, how do I access the variadic argument list?

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

In other words, what is the lambda equivalent to the following?

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

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

NOTE: As an aside, these signatures are related to logging, but please answer the question in a general (not logging) context.

推荐答案

std::function不支持可变函数. std::function 采用一种类型,看起来像这样:

Variadic functions are not supported by std::function. std::function takes one type, and it looks something like this:

template<class>
class function;  // Intentionally incomplete

template<class Ret, class... Args>
class function<Ret(Args...)> {
    // Deduce return type and argument types from function type
};

但是,这并不能推论可变函数的类型.因此void(const char*)可以工作(RetvoidArgs...const char*),但是void(const char*, ...)不能工作(因为这需要从Ret(Args..., ...)推导出来)

But this does not deduce the types for variadic function. So void(const char*) would work (Ret is void and Args... is const char*), but void(const char*, ...) would not work (As that would need to be deduced from Ret(Args..., ...))

要使用它创建函子对象,或者像使用fn1那样仅使用裸函数指针,或者使用

To make a functor object out of it, either just use a bare function pointer, like you did with fn1, or make do what the C standard library does with functions like vprintf:

decltype(auto) my_variadic_function(const char * format, ...) {
  va_list args;
  va_start(args, format);
  try {
      auto&& return_value = vmy_variadic_function(format, args);
  } catch (...) {
      va_end(args);
      throw;
  }
  va_end(args);
  return std::forward<decltype(return_value)>(return_value);
}

void vmy_variadic_function(const char* format, va_list args) {
    // Do stuff with args
}

然后在std::function<void(const char*, va_list)>中传递vmy_variadic_function.

这篇关于如何将`void(* fn)(const char *,...)`转换为`std :: function`,反之亦然的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆