Reputation: 107
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)
Upvotes: 0
Views: 485
Reputation: 7717
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()
.
Upvotes: 0
Reputation: 18964
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));
Upvotes: 0
Reputation: 249193
I think you want to wrap the weak_ptr in ref() to evaluate it lazily:
function<void()> weakPrintValue = bind(callWeakFunction, ref(weakValue));
Upvotes: 1