typedef void(*fn1)(const char *, ...);
typedef std::function<void(const char *, ...)> fn2; // has initializer but incomplete type
直觉上,这些对我来说实际上是一样的,但显然我的直觉让我失望了。我将如何协调这些数据类型?
fn2
为什么是不完整的类型?- 需要对
fn2
的签名进行哪些更改,以允许我为其分配fn1
类型? 创建要分配给
fn2
的 lambda 时,如何访问可变参数列表?换句话说,等价于以下的 lambda 是什么?
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
采用一种类型,它看起来像这样:
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..., ...)
中推导出来)
要从中创建一个仿函数对象,要么只使用一个裸函数指针,就像您对 fn1
所做的那样, 或者凑合 C 标准库对 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
}
然后通过vmy_variadic_function
在std::function<void(const char*, va_list)>
.
关于c++ - 如何将 `void(*fn)(const char *, ...)` 转换为 `std::function`,反之亦然,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55423225/