我试图玩弄std :: function和std :: bind,并且我加入了一个问题。我想构建一个通用结构,它允许我将std :: function绑定到成员函数,而不必事先知道成员函数的参数。我写这个东西访问违反std :: function分配给lambda
template<typename Class, typename Return, typename ...Args>
struct Caller
{
private:
std::function<Return(Args ...)> callerFunction;
Caller(const Caller&) = delete;
Caller(Caller&&) = delete;
Caller& operator=(const Caller&) = delete;
public:
~Caller() = default;
Caller() = default;
Caller(Class& instance, Return(Class::*function)(Args...))
{
callerFunction = [&](Args... args) { return (instance.*function)(args...); };
}
Return operator() (Args ... args)
{
return callerFunction(args...);
}
};
FYI我知道,函数的自变量是按值传递(我遇到使用带有可变参数模板普遍引用了一些问题,我将努力稍后)。
这里的问题是,当我用operator()触发函数时,我得到了访问冲突错误。我试图缩小这个问题,并创建了一个没有可变参数的结构(允许成员函数只有一个int作为参数),我看到将lambda赋给std :: function给了我相同的错误,但是如果我用占位符的std :: bind一切都很好。
试验地是这个
class A
{
public:
bool foo(int a)
{
std::cout << a << std::endl;
return true;
}
};
int main()
{
A a;
a.foo(9);
Caller<A, bool, int> caller(a, &A::foo);
caller(10);
std::cin.ignore();
}
使用拉姆达,做我需要保存的类的实例,以便正确地调用成员函数?
我很确定你有UB。在'Caller'的构造函数中,您通过值传递成员函数指针(因此将创建一个只存在于构造函数内部的指针副本),然后通过引用将其捕获到lambda中。所以当你调用'caller(10)'时,指针超出了范围。在这个例子中,'instance'很好,因为你通过引用将它传递给了构造函数,当调用'caller(10)'时,'a'仍然在范围内。 (虽然你应该假设未来会发生变化,并围绕它进行设计。) – 0x5453
还值得注意的是,已经存在一个'std :: mem_fn',它应该可以在lambdas或std :: bind中正常工作。 – 0x5453
好了解。我不明白的是我如何解决这个问题。 关于实例:在程序启动时,我将实例化一些类,这些变量将一直可用,直到程序结束。 – Astinog