这个问题与this answer中的DelayedCaller有关。

DelayedCaller绑定(bind)了一个函数指针及其参数,只要其参数不是比DelayedCaller的执行寿命短的事物的指针(将本地变量的string.c_str()作为参数),便可以像魅力一样工作。

为了避免这个问题,我创建了一个存储有问题的参数的存储,该存储由模板函数扫描参数来处理。

我现在需要的是相反的情况:我希望通过评估作为参数提供给DelayedCaller的指针的地址,在相同类型的不同对象上调用成员函数。

我目前看到两种解决方法:

  • std::placeholders:在创建DelayedCaller时不提供对象,而是提供了call方法。
  • 一个对象指针的包装器,该包装器取消引用两次(重载->)。

  • 我偏爱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

    10-06 08:45