如何将`void(* fn)(const char *,...)`转换为`std :: function`,反之亦然 [英] How to translate `void(*fn)(const char *, ...)` to `std::function` and vice versa
问题描述
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?
-
fn2
如何是不完整的类型? -
fn2
的签名需要进行哪些更改,才能为我指定fn1
类型? -
在创建要分配给
fn2
的lambda时,如何访问可变参数列表?
- How is
fn2
an incomplete type? - What changes are necessary to the signature of
fn2
, to allow me to assign it a type offn1
? 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*)
可以工作(Ret
是void
,Args...
是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屋!