简体   繁体   中英

C++ bind to weak_ptr not working

I have a simple test where I am trying to bind a weak_ptr argument to a global function that takes a weak_ptr, and invokes a method if the backing pointer is still valid.

This seems to work when I create a lambda with the weak pointer. It also works if I call the global method directly, with the weak_ptr. However if I bind the global function to the weak_ptr in advance, it does not seem to work. Following watered down code illustrates the question.

I must be missing something simple. Any clues?

#include <iostream>
#include <functional>
#include <algorithm>
#include <memory>

using namespace std;

class MyValue : public enable_shared_from_this<MyValue>
{
    public:
        MyValue (int i)
        {
            value = i;
        }

        ~MyValue()
        {
        }

        int getValue() { return value; }

        void printValue() { cout << value << endl; }

    private:

        int value;
};

void callWeakFunction (weak_ptr<MyValue> weakValue)
{
    shared_ptr<MyValue> strongPtr = weakValue.lock();

    if (strongPtr)
    {
        strongPtr->printValue();
    }
    else
    {
        cout << "Sorry, your backing pointer is gone" << endl;
    }
}

int main()
{
    weak_ptr<MyValue> weakValue;

    // Try binding a global function to the weak pointer, doesn't seem to work
    function<void()> weakPrintValue = bind(callWeakFunction, weakValue);

#if 0
    // Create a lambda - this works fine
    function<void()> weakPrintValue ([&weakValue]()
                       {
                           shared_ptr<MyValue> ptr = weakValue.lock();
                           if(ptr)
                           {
                               ptr->printValue();
                           }
                           else
                           {
                               cout << "Sorry, backing pointer is gone" << endl;
                           }
                       });
#endif

    {
        shared_ptr<MyValue> value = make_shared<MyValue>(7);

        weakValue = value;

        // Backing pointer is present
        weakPrintValue();    // This does not work, but callWeakFunction (weakValue) works fine
    }

    // No backing pointer
    weakPrintValue();
}

Resulting output:

Sorry, your backing pointer is gone
Sorry, your backing pointer is gone

Expecting the first weakPrintValue to print the value (7)

我认为您想将weak_ptr包装在ref()中以懒惰地对其进行评估:

function<void()> weakPrintValue = bind(callWeakFunction, ref(weakValue));

I wouldn't expect either to work. In both cases you're capturing the initial value of weak_value when it is empty. To be affected by the subsequent assignment to it you need to capture by reference instead. So in the lambda you need [&weak_value] , and for the bind you need

bind(callWeakFunction, cref(weakValue));

I believe bind() captures weakValue by value. It returns resulting object that has it's own copy of weakValue . When you change local weakValue it does not affect the copy inside of the object returned by bind() .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM