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);