这个问题与this answer中的DelayedCaller有关。
DelayedCaller绑定(bind)了一个函数指针及其参数,只要其参数不是比DelayedCaller的执行寿命短的事物的指针(将本地变量的string.c_str()作为参数),便可以像魅力一样工作。
为了避免这个问题,我创建了一个存储有问题的参数的存储,该存储由模板函数扫描参数来处理。
我现在需要的是相反的情况:我希望通过评估作为参数提供给DelayedCaller的指针的地址,在相同类型的不同对象上调用成员函数。
我目前看到两种解决方法:
我偏爱2.而不是1。(我不想在使用call()时必须提供参数),但可能甚至没有考虑其他选项。
例:
#include <iostream>
#include <string>
#include <functional>
#include <memory>
class MyClass
{
float myFloat;
public:
MyClass(float f):myFloat(f){}
void myFunc(int arg1)
{
std::cout << arg1 << ", " << myFloat << '\n';
}
};
class MyContainer
{
public:
MyClass* object;
};
// DelayedCaller implementation
class DelayedCaller
{
public:
template <typename TFunction, typename... TArgs>
static std::shared_ptr<DelayedCaller> setup(TFunction&& a_func,
TArgs&&... a_args)
{
return std::shared_ptr<DelayedCaller>(new DelayedCaller(
std::bind(std::forward<TFunction>(a_func),
std::forward<TArgs>(a_args)...)));
}
void call() const { func_(); }
private:
using func_type = std::function<void()>;
DelayedCaller(func_type&& a_ft) : func_(std::forward<func_type>(a_ft)) {}
func_type func_;
};
int main()
{
MyContainer container;
MyClass* c1 = new MyClass(45.6);
container.object = c1;
// the next line is the critical one. Instead of myFunc being called
// on the current value of container.object, it should be called on
// the one container.object is holding when caller is called.
auto caller(DelayedCaller::setup(&MyClass::myFunc, container.object, 123));
caller->call();
MyClass* c2 = new MyClass(22.8);
container.object = c2;
caller->call();
delete c1;
delete c2;
return 0;
}
最佳答案
std::reference_wrapper
可能会有所帮助,请使用:
auto caller(DelayedCaller::setup(&MyClass::myFunc, std::ref(container.object), 123));
Demo