我想将一个指向函数的指针存储为成员变量,该函数可以使用可变数量的不同类型的参数。
我一直在尝试使用的基本构造是
template <typename... Args>
using ArgsFuncPointer = void(*)(Args...);
template<typename... Args> void varArgsFunc(Args&&... args) { }
{
ArgsFuncPointer<int, float> funcPointer = varArgsFunc;
funcPointer(1, 2.0);
}
问题是varArgsFunc
无法转换为ArgsFuncPointer<int, float>
有关(不起作用的)示例,请参见coliru。
最终,我希望能够执行以下操作:
template <typename... Args> class Foo
{
public:
Foo(Args&&... args)
{
func(args);
}
VarArgsFuncPointer func;
}
更新
事实证明,无法编译的原因是ArgsFuncPointer
和varArgsFunc
之间的签名存在细微差异。对于ArgsFuncPointer
,参数包是通过右值引用传递的,而对于varArgsFunc
,参数包是按值传递的。
这有效:
template <typename... Args>
using ArgsFuncPointer = void(*)(Args&&...);
template<typename... Args> void varArgsFunc(Args&&... args) { }
{
ArgsFuncPointer<int, float> funcPointer = varArgsFunc;
funcPointer(1, 2.0);
}
工作示例here
答案 0 :(得分:3)
问题在于varArgsFunc
是模板而不是特定功能,而ArgsFuncPointer<int, float>
是指向特定功能的指针。
未经测试,但是您应该能够通过指定其模板参数来指定实际的函数实例:
ArgsFuncPointer<int, float> funcPointer = varArgsFunc<int, float>;
// ^^^^^^^^^^^^
// Must specify template arguments
另一方面,我建议您使用std::function
而不是指向非成员函数的指针。这样您就可以使用std::bind
或lambdas或几乎任何可调用对象。
使用std::function
与您现在所拥有的非常相似:
template <typename... Args>
using ArgsFuncPointer = std::function<void(Args...)>;
然后使用lambda可以执行类似的操作
ArgsFuncPointer<int, float> funcPointer = [](int i, float f)
{
varArgsFunc(i, f); // Call the real function
};
答案 1 :(得分:1)
您在做类似的事情吗
template <typename... Args>
using ArgsFuncPointer = void(*)(Args...);
template <typename... Args> class Foo
{
public:
Foo(Args&&... args)
{
func(std::forward<Args>(args)...);
}
ArgsFuncPointer<Args...> func;
};
在表达式中使用包时需要扩展。