How to reset an std::function? - c++

std::function can be empty, and it's convertible to bool to test if it has a target or not. But, how to set it to null after you've assigned something to it?
int main()
{
std::function<void()> f = []() { return 4; };
// how to reset to null, to it's initial state when default constructed.
}

You can either:
assign nullptr to it:
f = nullptr;
assign an empty function to it:
f = std::function<void()>{};
// or:
f = decltype(f){};
swap() it with another empty function:
std::function<void()>{}.swap(f);
// or:
decltype(f){}.swap(f);

The simplest way, I use it:
f = {};
https://godbolt.org/z/hzEq3xo4e
#include <functional>
int main() {
std::function<void()> f = []() { return 4; };
f = {};
}

Assign nullptr to it to make it empty.
f = nullptr;

Related

Can I capture by reference a returned value?

If a lambda captures by reference a value that will be returned along with the lambda. Does the reference holds when calling the lambda?
#include <memory>
#include <functional>
struct context_with_callback {
bool flag = false;
std::function<void()> callback;
};
std::unique_ptr<context_with_callback> make_context() {
auto ctx_with_callback = std::make_unique<context_with_callback>();
ctx_with_callback->callback = [&] () {
ctx_with_callback->flag = true;
};
return ctx_with_callback; // am I allowed to do that?
};
int main() {
auto ctx = make_context();
ctx->callback(); // will this be always valid?
return 0;
}
If it is not valid, I could capture the raw pointer by copy instead, but maybe there is a better way?
You "can" capture an automatic variable by reference, but that won't be useful if you return the lambda because the reference will dangling as soon as the function returns.
return ctx_with_callback; // am I allowed to do that?
Technically yes, but it won't be useful.
ctx->callback(); // will this be always valid?
This is never valid given the current implementation.
This would work, and would even allow returning the context by value, avoiding dynamic allocation if you so prefer:
struct context_with_callback {
bool flag = false;
std::function<void(context_with_callback&)> callback_object;
void callback() {
callback_object(*this);
}
};
context_with_callback make_context() {
return {
.flag = false,
.callback_object = [](context_with_callback& ctx_with_callback) {
ctx_with_callback.flag = true;
},
};
}

Access two-step-declared member in lambda setup

Don't know how to describe it better. Here's the code. This fails to compiler on gcc 4.9.2 (Debian 8.5), tough I think it compiled in a previous version. The problem seems to occur only if I access the later-declared structure's member as a default argument in the lambda setup. The other shown cases work.
// Test program
class C1
{
private:
// Forward-declared
struct S_Private;
S_Private* d_;
public:
void func();
};
struct C1::S_Private
{
int a;
};
void C1::func()
{
// This will work
int test = d_->a;
// Accessing the d_->a as a default argument in lambda setup
// will NOT work:
// error: invalid use of non-static data member ‘C1::d_’
auto some_lambda = [&](int arg = d_->a)
{
// This will also work
int test2 = d_->a;
};
}
int main(void)
{
}
Unfortunately in auto some_lambda = [&](int arg = d_->a), d_->a is not the d_->a you used earlier in the function but instead d_->a is being called on the this that you captured using [&]. Because it is a member variable you cannot use it as a default argument in a function.
Essentially
auto some_lambda = [&](int arg = d_->a)
{
// This will also work
int test2 = d_->a;
};
Is
struct some_unique_name
{
some_unique_name(C1*& var) : this_(var) {}
auto operator()(int arg = this_->d_->a)
{
// This will also work
int test2 = d_->a;
}
C1*& this_;
};
auto some_lambda = some_unique_name{this};
As you can see from the translation it uses the class member, not the object in the class itself.

std::bind vs std::shared_ptr

Can't understand how to use shared_ptr binded to class function.
An error occurrs at line USE because compiler can't convert shared_ptr to A.
#include <functional>
class A {
public:
const bool check(void) const { return true; };
};
int _tmain(int argc, _TCHAR* argv[]) {
const std::function<const bool(const A)> f_check = &A::check;
auto a = std::make_shared<const A>();
auto f_check_a = std::bind(f_check, a); // line BIND
auto res = f_check_a(); // line USE - ERROR!!!
return 0;
}
I can replace line BIND to access real value of smart pointer:
int _tmain(int argc, _TCHAR* argv[]) {
auto f_check = &A::check;
auto a = std::make_shared<const A>();
auto f_check_a = std::bind(f_check, *a.get()); // line BIND
auto res = f_check_a(); // line USE - NO ERRORS
return 0;
}
Now code is compiled and may be it will work.
But I'd like to know - is it acceptable way to use raw value from smart pointer? May I somehow use shared_ptr instead raw value?
UPD2:
Looks like my colleague have found a nice workaround:
class A {
public:
const bool check(void) const { return true; };
};
using p_func = const bool(A::*)() const;
int _tmain(int argc, _TCHAR* argv[]) {
auto a = std::make_shared<const A>();
p_func b = &A::check;
auto f_check_a = std::bind(b, a);
auto res = f_check_a();
}
Now I can send b as argument and bind to shared_ptr.
UPD:
I can't use lambda in my real task.
Here is some more code from real project:
#include <functional>
#include <algorithm>
class Block {
public:
const bool check1(void) const { return false; };
const bool check2(void) const { return false; };
const bool check3(void) const { return false; };
};
using block_t = std::shared_ptr<const Block>;
class Worker {
private:
std::vector<const block_t> _container;
public:
void processor(const std::function<const bool(const Block)> f_check) {
block_t my_block = nullptr;
auto lambda = [my_block, f_check](const block_t block) mutable {
auto function_check = std::bind(f_check, *block.get());
if (function_check()) {
my_block = block;
return true;
}
return false;
};
std::find_if(_container.begin(), _container.end(), lambda);
}
};
void test(block_t block) {
Worker worker;
worker.processor(&Block::check1);
worker.processor(&Block::check2);
worker.processor(&Block::check3);
}
UPD3:
Fixed code without smart pointer dereferencing:
#include <functional>
#include <algorithm>
class Block {
public:
const bool check1(void) const { return false; };
const bool check2(void) const { return false; };
const bool check3(void) const { return false; };
};
using block_t = std::shared_ptr<const Block>;
using p_func = const bool(Block::*)() const;
class Worker {
private:
std::vector<const block_t> _container;
public:
void processor(p_func f_check) {
block_t my_block = nullptr;
auto lambda = [my_block, f_check](const block_t block) mutable {
auto function_check = std::bind(f_check, block);
if (function_check()) {
my_block = block;
return true;
}
return false;
};
std::find_if(_container.begin(), _container.end(), lambda);
}
};
void test(block_t block) {
Worker worker;
worker.processor(&Block::check1);
worker.processor(&Block::check2);
worker.processor(&Block::check3);
}
Your problem is that you are first creating a std::function, expecting an A instance, from a member function and than trying to bind it to a shared_ptr. You can skip that part:
auto a = std::make_shared<const A>();
auto f_check_a = std::bind(&A::check, a);
auto res = f_check_a();
std::bind knows how to directly bind a member function to a shared_ptr.
Must you use std::bind? You could use a lambda instead.
auto f_check_a = [=]{ return a->check(); };
function expects to get an instance of A, not a shared_ptr<A>, so the answer to your question is basically yes, I believe.
However, I would make 2 changes to your code as follows (see my comments):
const std::function<const bool(const A&)> f_check = &A::check; // <-- Added & after A here
auto a = std::make_shared<const A>();
auto f_check_a = std::bind(f_check, *a); // <-- no need to call get() on a
auto res = f_check_a(); // line USE - ERROR!!!
But I'd like to know - is it acceptable way to use raw value from smart pointer?
Yes, but you can just write *a instead of *a.get()
However, the call wrapper returned from bind has a reference to theA object, so it is your responsibility to ensure the reference remains valid. If you bound the shared_ptr then that would increase the reference count and keep the object alive.
May I somehow use shared_ptr instead raw value?
If you use std::function<const bool(const A)> then you cannot pass a shared_ptr<const A>.
When you use std::function<const bool(const A)> you create a callable type that has exactly the call signature const bool(const A) and so you have to pass it an argument that is convertible to const A, and shared_ptr<const A> is not convertible to const A.
A workaround would be to use a lambda to combine the std::function and shared_ptr:
auto function_check = [] { return f_check(*block); };
if (function_check()) {
However, you are trying to solve a problem that shouldn't exist, just do this instead:
if (f_check(*block)) {
my_block = block;
return true;
}
return false;
Then you don't need to bind anything.

Binding to a weak_ptr

Is there a way to std::bind to a std::weak_ptr? I'd like to store a "weak function" callback that automatically "disconnects" when the callee is destroyed.
I know how to create a std::function using a shared_ptr:
std::function<void()> MyClass::GetCallback()
{
return std::function<void()>(std::bind(&MyClass::CallbackFunc, shared_from_this()));
}
However the returned std::function keeps my object alive forever. So I'd like to bind it to a weak_ptr:
std::function<void()> MyClass::GetCallback()
{
std::weak_ptr<MyClass> thisWeakPtr(shared_from_this());
return std::function<void()>(std::bind(&MyClass::CallbackFunc, thisWeakPtr));
}
But that doesn't compile. (std::bind will accept no weak_ptr!) Is there any way to bind to a weak_ptr?
I've found discussions about this (see below), but there seems to be no standard implementation. What is the best solution for storing a "weak function", in particular if Boost is not available?
Discussions / research (all of these use Boost and are not standardized):
weak_function
weak_ptr binding
"weak" binding (and a fix for it)
weak_fn
Another weak_fn
std::weak_ptr<MyClass> thisWeakPtr(shared_from_this());
return std::function<void()>(std::bind(&MyClass::CallbackFunc, thisWeakPtr));
You should never do this. Ever.
MyClass::CallbackFunc is a non-static member function of the class MyClass. Being a non-static member function, it must be called with a valid instance of MyClass.
The entire point of weak_ptr is that it isn't necessarily valid. You can detect its validity by transforming it into a shared_ptr and then testing if the pointer is NULL. Since weak_ptr is not guaranteed to be valid at all times, you cannot call a non-static member function with one.
What you're doing is no more valid than:
std::bind(&MyClass::CallbackFunc, nullptr)
It may compile, but it will eventually crash when you try to call it.
Your best bet is to use actual logic, to not call the callback function if the weak_ptr is not valid. bind is not designed to do logic; it just does exactly what you tell it to: call the function. So you need to use a proper lambda:
std::weak_ptr<MyClass> thisWeakPtr(shared_from_this());
return std::function<void()>([thisWeakPtr]()
{
auto myPtr = thisWeakPtr.lock();
if(myPtr)
myPtr->CallbackFunc()
});
I was able to create weak_pointers of std::function and tested it with clang-3.2 (you didn't give any compiler restrictions).
Here's a sample app that creates and tests what I believe you are asking for:
#include <functional>
#include <memory>
#include <iostream>
typedef std::function<void(void)> Func;
typedef std::shared_ptr<Func> SharedFunc;
typedef std::weak_ptr<Func> WeakFunc;
void Execute( Func f ) {
f();
}
void Execute( SharedFunc sf ) {
(*sf)();
}
void Execute( WeakFunc wf ) {
if ( auto f = wf.lock() )
(*f)();
else
std::cout << "Your backing pointer went away, sorry.\n";
}
int main(int, char**) {
auto f1 = [](){ std::cout << "Func here.\n"; };
Execute( f1 );
auto f2 = [](){ std::cout << "SharedFunc here.\n"; };
SharedFunc sf2( new Func(f2) );
Execute( sf2 );
auto f3 = [](){ std::cout << "WeakFunc here.\n"; };
SharedFunc sf3( new Func(f3) );
WeakFunc wf3( sf3 );
Execute( wf3 );
// Scoped test to make sure that the weak_ptr is really working.
WeakFunc wf4;
{
auto f4 = [](){ std::cout << "You should never see this.\n"; };
SharedFunc sf4( new Func(f4) );
wf4 = sf4;
}
Execute( wf4 );
return 0;
}
The output was:
~/projects/stack_overflow> clang++-mp-3.2 --std=c++11 --stdlib=libc++ weak_fun.cpp -o wf && ./wf
Func here.
SharedFunc here.
WeakFunc here.
Your backing pointer went away, sorry.
#include <iostream>
#include <string>
#include <memory>
#include <functional>
using namespace std;
template < typename T > class LockingPtr {
std :: weak_ptr < T > w;
public:
typedef shared_ptr < T > result_type;
LockingPtr ( const std :: shared_ptr < T > & p ) : w ( p ) { }
std :: shared_ptr < T > lock ( ) const {
return std :: shared_ptr < T > ( w );
}
std :: shared_ptr < T > operator-> ( ) const {
return lock ( );
}
template < typename ... Args > std :: shared_ptr < T > operator( ) ( Args ... ) const {
return lock ( );
}
};
template < typename T > LockingPtr < T > make_locking ( const shared_ptr < T > & p ) {
return p;
}
namespace std {
template < typename T > struct is_bind_expression < LockingPtr < T > > :
public true_type { };
}
int main() {
auto p = make_shared < string > ( "abc" );
auto f = bind ( & string :: c_str, make_locking ( p ) );
cout << f ( ) << '\n';
p.reset ( );
try {
cout << f ( ) << '\n';
} catch ( const exception & e ) {
cout << e.what ( ) << '\n';
}
// your code goes here
return 0;
}
output:
abc
bad_weak_ptr
I know this is an old question, but I have the same requirement and I'm sure I'm not alone.
The solution in the end for me was to return a function object that returns a boost::optional<> depending on whether the function was called or not.
code here:
#include <boost/optional.hpp>
#include <memory>
namespace value { namespace stdext {
using boost::optional;
using boost::none;
struct called_flag {};
namespace detail
{
template<class Target, class F>
struct weak_binder
{
using target_type = Target;
using weak_ptr_type = std::weak_ptr<Target>;
weak_binder(weak_ptr_type weak_ptr, F f)
: _weak_ptr(std::move(weak_ptr))
, _f(std::move(f))
{}
template<class...Args,
class Result = std::result_of_t<F(Args...)>,
std::enable_if_t<not std::is_void<Result>::value>* = nullptr>
auto operator()(Args&&...args) const -> optional<Result>
{
auto locked_ptr = _weak_ptr.lock();
if (locked_ptr)
{
return _f(std::forward<Args>(args)...);
}
else
{
return none;
}
}
template<class...Args,
class Result = std::result_of_t<F(Args...)>,
std::enable_if_t<std::is_void<Result>::value>* = nullptr>
auto operator()(Args&&...args) const -> optional<called_flag>
{
auto locked_ptr = _weak_ptr.lock();
if (locked_ptr)
{
_f(std::forward<Args>(args)...);
return called_flag {};
}
else
{
return none;
}
}
weak_ptr_type _weak_ptr;
F _f;
};
}
template<class Ret, class Target, class...FuncArgs, class Pointee, class...Args>
auto bind_weak(Ret (Target::*mfp)(FuncArgs...), const std::shared_ptr<Pointee>& ptr, Args&&...args)
{
using binder_type = decltype(std::bind(mfp, ptr.get(), std::forward<Args>(args)...));
return detail::weak_binder<Target, binder_type>
{
std::weak_ptr<Target>(ptr),
std::bind(mfp, ptr.get(), std::forward<Args>(args)...)
};
}
}}
called (for example) like so:
TEST(bindWeakTest, testBasics)
{
struct Y
{
void bar() {};
};
struct X : std::enable_shared_from_this<X>
{
int increment(int by) {
count += by;
return count;
}
void foo() {
}
Y y;
int count = 0;
};
auto px = std::make_shared<X>();
auto wf = value::stdext::bind_weak(&X::increment, px, std::placeholders::_1);
auto weak_call_bar = value::stdext::bind_weak(&Y::bar, std::shared_ptr<Y>(px, &px->y));
auto ret1 = wf(4);
EXPECT_TRUE(bool(ret1));
EXPECT_EQ(4, ret1.get());
auto wfoo1 = value::stdext::bind_weak(&X::foo, px);
auto retfoo1 = wfoo1();
EXPECT_TRUE(bool(retfoo1));
auto retbar1 = weak_call_bar();
EXPECT_TRUE(bool(retbar1));
px.reset();
auto ret2 = wf(4);
EXPECT_FALSE(bool(ret2));
auto retfoo2 = wfoo1();
EXPECT_FALSE(bool(retfoo2));
auto retbar2 = weak_call_bar();
EXPECT_FALSE(bool(retbar2));
}
source code and tests available here:
https://github.com/madmongo1/valuelib
Not sure why that definition is not in boost. There must be a good reason (how to deal with lock fail? Is throwing from there acceptable? Thread safety?) Anyway, that will validate your callee.
namespace boost {
template<class T> T * get_pointer(boost::weak_ptr<T> const& p)
{
boost::shared_ptr< T > _strong = p.lock();
if( _strong )
return _strong.get();
else
throw 1;
}
}
int main(int arg, char *argv[])
{
boost::weak_ptr< MyType > weak_bad;
{
boost::shared_ptr< MyType > strong(new MyType);
boost::weak_ptr< MyType > weak(strong);
boost::function< void(int) > _func1 = boost::bind(&MyType::setX, weak, _1);
_func1(10);
weak_bad = strong;
}
try {
boost::function< void(int) > _func1 = boost::bind(&MyType::setX, weak_bad, _1);
_func1(10);
}
catch(...)
{
std::cout << "oops!";
}
return 0;
};
Another solution:
You could wrap the std::function. The class producing the callback would hold a shared_ptr< wrapper_type > and provide a weak_ptr< wrapper_type >. The producing object would be the one with the ownership, if it goes out of scope, callers won't be able to promote their weak reference. Your wrapper type could forward call arguments to the std::function or simply expose it via its interface. Just make sure that on copy you properly handle the shared_ptr on the wrapper (don't share).
template< typename _Ty >
struct wrapper
{
wrapper(_Ty wrappe)
: _wrappe(wrappe)
{ }
_Ty _wrappe;
};
...
boost::shared_ptr< wrapper < std::func< ... > > _func(new wrapper < std::func< ... > );
...
boost::weak_ptr< wrapper < std::func< ... > getCallBack() {
return _func;
}
How about this? it works only for actions std::function<void()> but perhaps it can be generalized for arbitrarily parameterized functions.
#include <memory>
#include <functional>
template<typename T>
void
perform_action_or_ignore_when_null(
std::weak_ptr<T> weak,
std::function< void( std::shared_ptr<T> ) > func
)
{
if(auto ptr = weak.lock())
func(ptr);
}
template<typename T>
std::function<void()>
ignore_when_null(
std::weak_ptr<T> weak,
std::function< void( std::shared_ptr<T> ) > func
)
{
return std::bind(perform_action_or_ignore_when_null<T>, weak, func);
}
here's an example usage:
struct Foo {
Foo() {}
void bar() {
std::cout << "hello world!" << std::endl;
}
};
void main()
{
std::weak_ptr<Foo> weakfoo;
std::function<void(std::shared_ptr<Foo>)> foobar = std::bind(&Foo::bar, std::placeholders::_1);
{
auto foo = std::make_shared<Foo>();
weakfoo = foo;
auto f = ignore_when_null(weakfoo, foobar);
f(); // prints "hello world!";
}
auto g = ignore_when_null(weakfoo, foobar);
g(); // does nothing
}
You can bind weak_ptr to the function as one of parameters,
and check it when the function is called.
For example:
std::function<void()> MyClass::GetCallback()
{
std::weak_ptr<MyClass> thisWeakPtr(shared_from_this());
return std::function<void()>(std::bind(&MyClass::CallbackFunc, this,
thisWeakPtr));
}
void MyClass::CallbackFunc(const std::weak_ptr<MyClass>& thisWeakPtr)
{
if (!thisWeakPtr.lock()) {
return;
}
// Do your callback job.
// ...
}

VC++ "Re-use" a function?

How can I re-use a function?
Okay lets say I have this "main" function below:
bool A = false;
bool B = true;
void MainFunction(bool Whatever) {
if(!Whatever) {
A = true;
if(A) {
B = false;
} else if(!A) {
B = true;
}
}
}
Now I want to make a new function using the MainFunction, something like this:
MainFunction ANewFunction(false);
MainFunction AnotherNewFunction(true);
Obviously that won't work, so is there any way to "re-use" a function as a different function?
You're welcome to have one function call another. For example:
void ANewFunction() {
MainFunction(false);
}
void AnotherNewFunction() {
MainFunction(true);
}
You can even get fancy:
#include <functional>
auto ANewFunction = std::bind(&MainFunction, false);
auto AnotherNewFunction = std::bind(&MainFunction, true);
Either way, you can call ANewFunction or AnotherNewFunction, and MainFunction will get called with the given argument. (In the latter case, they're not really functions anymore. They're called function objects, or functors, but you cal still call them just like ordinary functions: ANewFunction().)
You can't "re-use" functions, at least not in the way I understand your question.
But you can create a new function that calls the original function and then does some additional work of its own. For example:
void PrevFunction(int one)
{
int i = one;
// do whatever
}
void NewFunction(int one)
{
PrevFunction(one);
// do new stuff
// ...
}
You could also define a class, and then use inheritance and virtual functions to modify the behavior of a particular set of functions from the base class.
typedef int (*function_t)(int); // new type - defines function type - address of function
// your function, PrevFunction is simply variable holding address of the function:
int PrevFunction(int one) { return one; }
// new variable of type function_t initialized by PrevFunction address:
function_t NewFunction = PrevFunction;
//And finally we can use either PrevFunction or NewFunction - they point to the same function body:
int a = PrevFunction(1); // a == 1
int b = NewFunction(2); // a == 2
Simply call MainFunction from your other function?
void ANewFunction()
{
MainFunction(false);
}
void AnotherNewFunction()
{
MainFunction(true);
}
If your question is how do you make AnotherNewFunction refer to a different A and B than ANewFunction, the answer is you can't, at least not without help from MainFunction. You can, however, update MainFunction:
void MainFunction(bool Whatever, bool& A, bool& B) {
if(!Whatever) {
A = true;
if(A) {
B = false;
} else if(!A) {
B = true;
}
}
}
bool A1 = false;
bool B1 = true;
void ANewFunction()
{
MainFunction(false, A1, B1);
}
bool A2 = false;
bool B2 = true;
void AnotherNewFunction()
{
MainFunction(true, A2, B2);
}
Another new-fangled solution, using lambda's:
auto ANewFunction = [](){ MainFunction(false); }
auto AnotherNewFunction = [](){ MainFunction(true); }