C++ 变量模板作为std::函数的参数
我想构建一个结构,允许我使用未定义数量的参数调用成员函数。现在我写了这样的东西C++ 变量模板作为std::函数的参数,c++,function,c++11,variadic-templates,C++,Function,C++11,Variadic Templates,我想构建一个结构,允许我使用未定义数量的参数调用成员函数。现在我写了这样的东西 template<typename Class, typename Return, typename ... Args> struct Caller { private: std::function<Return(Args ...)> callerFunction; Caller() = delete; Caller(const Caller&) = dele
template<typename Class, typename Return, typename ... Args>
struct Caller
{
private:
std::function<Return(Args ...)> callerFunction;
Caller() = delete;
Caller(const Caller&) = delete;
Caller(Caller&&) = delete;
Caller& operator=(const Caller&) = delete;
public:
~Caller() = default;
Caller(Class& instance, Return(Class::*function)(Args ...))
{
callerFunction = [&instance, function](Args... args)
{
return (instance.*function)(args ...);
};
}
Return operator() (Args ... args)
{
return callerFunction(args ...);
}
};
现在的问题是:如果没有双精度&?
int&&
与int
不同,我为什么还要声明函数呢。如果您的方法采用int
,则不会采用int&
。它们是不同的类型
成员函数指针的不同签名之间没有转换
转发引用并不是什么神奇的事情。它们依赖于推导规则(并且在推导的上下文中不使用上面的Args&&…
)和引用折叠规则
因此,你的
Return operator() (Args&& ... args)
这也是错误的。如果Args…
是int
,那么您将无法使用inta调用上述函数;blah.operator()(a)
作为a
不会绑定到int&
老实说,您的整个类型都应该被抛出并替换为std::function
<代码>类是对函数功能的一个无用的缩小,而且包装器也不会增加太多内容
如果用户真的需要复制您的构造函数,可以使用
std::bind(&a::foo,std::ref(a))
,或者在这样定义类模板时使用std::bind(&a::foo,std::ref(a))
:
template <typename T>
struct A {
A(T&& param)
}
模板
结构A{
A(T&参数)
}
然后创建Instance:
A<int> myInstance(someIntVariable);
myInstance(someIntVariable);
它不会编译。原因是,T
的类型由您明确指定(作为int
,在A
中),并且您的类构造函数参数不再是T&
,而是int&
,因此它不再是通用引用(同时接受左值和右值引用),而是常规右值引用
接下来,如果将某个整数传递给它,则会出现类型错误匹配错误,因为在需要右值引用时传递了一个正则变量
在您的示例中,您显式定义了函数签名,因此同样的应用-构造函数要求函数引用Args…,但事实并非如此
我认为最好解释一下您使用什么编译器?它在Visual Studio 2017中工作。并向我们展示如何创建调用方的实例。我在Visual Studio 2013上,我做了如下调用方调用方(a,&a::foo)代码>。无论如何,我会在必要时使用std::forward
来更改结构。我正在尝试VS2017,我也遇到了同样的问题。我使用的完整代码在这里,谢谢你的解释,现在它是如此明显!我唯一的疑问是:我在任何情况下都不需要使用forward,因为我指定了要传递给函数的每个变量的类型,对吗?我甚至不需要在operator()函数中使用forward,我使用它调用带有参数的成员函数,对吗?@Astinog没错。std::forward只能与通用引用一起使用。它的唯一用途是将参数(forward)传递给另一个函数,而不改变其类型,因此,如果T&&将被传递一个左值,那么左值将被传递,如果右值,那么右值。如果你在谷歌上搜索“C++中的完美转发”,你可以阅读更多关于它的信息,关于这个主题有很多资源:)
A<int> myInstance(someIntVariable);