std::函数是否可以用于存储带有可变参数的函数
Can std::function be used to store a function with variadic arguments
我在应用程序中传递了一个结构,其中包含一组回调函数:
typedef struct {
std::function<void (void)> f1;
std::function<void (int)> f2;
std::function<int (float *)> f3;
// ... and so on
} CallbackTable;
根据当前系统状态,我通过将不同的函数绑定到各种回调来处理应用程序中的状态控制;它运行良好。
我现在想做的是添加几个额外的回调,其中签名包含可变数量的参数,类似于printf:例如,
std::function<int (const char * format, ...)> printToStdOut;
这个不起作用。在Visual C++中,我收到一条错误消息,上面写着:
error C2027: use of undefined type 'std::_Get_function_impl<_Fty>'
我仍在摸索C++语法的这一领域,如果能给我一些建议,我将不胜感激。我的首要目标是能够拨打以下电话:
myCallbackTable.printToStdOut("I've just eaten %d bananasrn", nBananas);
并根据系统状态将输出定向到控制台、文件或GUI窗口。
编辑:原始答案是错误的,经过修改,但仍然可能不是一个好答案,将其留在这里用于教育目的:
许多可变参数函数都有一个va_list版本。例如CCD_ 1具有CCD_。这些变体显式地采用va_list而不是省略号。
#include <iostream>
#include <functional>
#include <cstdarg>
int main()
{
std::function<int(const char*,va_list)> test2(vprintf);
return 0;
}
然而,援引它是一种痛苦。
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);
}
原来的帖子有什么问题(谢谢/u/T.C.):std::function<int(const char*,va_list)> test2(printf)
编译,我认为这意味着它"有效"。然而,它之所以编译,是因为printf可以接受任何类型的参数(包括va_list),而std::function
只检查是否可以用这种方式调用它。
根据@MadScienceDreams的建议,这对我来说效果相当好…
首先,我在结构中定义了std::函数对象的可变参数版本,然后利用这是C++而不是C的事实添加了一些方法:
typedef struct {
std::function<void (void)> f1;
std::function<void (int)> f2;
std::function<int (float *)> f3;
// ... and so on
std::function<int (const char * format, va_list args)> vprintToStdOut;
std::function<int (const char * format, va_list args)> vprintToStdErr;
int printToStdOut(const char * format, ...)
{
va_list ap;
va_start(ap, format);
int count = vprintToStdOut(format, ap);
va_end(ap);
return count;
}
int printToStdErr(const char * format, ...)
{
va_list ap;
va_start(ap, format);
int count = vprintToStdErr(format, ap);
va_end(ap);
return count;
}
} CallbackTable;
控制台输出的变量参数函数的默认实现是:
myCallbackTable.vprintToStdOut = std::bind(vfprintf, stdout, _1, _2);
myCallbackTable.vprintToStdErr = std::bind(vfprintf, stderr, _1, _2);
从这一点来看,我可以使用我希望使用的语法:
myCallbackTable.printToStdOut("I like to eat at least %d bananas a dayrn", nBananas);
相关文章:
- C++ gmock - 我们如何在单元测试 cpp 文件中读取/获取 cpp 文件函数的参数值
- 访问函数变体时"Invalid conversion"错误
- 创建函数变体向量时"No matching function for call"错误
- 如何使用 SFINAE 来防止模板函数变窄?
- 如何在 c++ 中将 1 个函数变量值发送到另一个函数
- C++记录每个函数和参数值
- 谷歌模拟函数改变参数值
- 将函数形参的实参解包到c++模板类
- 函数对象应该是函数实参还是它的引用?
- 如何传递操作符作为默认函函数实参
- c++ const函数形参.有没有一种方法可以只声明函数的单个签名?
- Const正确性- Const指针作为函数实参
- 关于将指向数组的指针作为函数形参的混淆
- 将非const引用使用auto-keyword声明的lambda作为实参传递给std::函数形参类型
- 通过函数实参而不是模板形参获取元组的元素
- 在函数实参中使用模板形参不适用gcc4.8
- 作为函数形参传递的Vector初始化器列表
- 指向函数形参的指针vs函数形参
- 在模板化类和函数上下文中以默认值作为函数形参的函子:-)
- 带std::函数形参的重载操作符