So I am writing a project for an OOP course. I came across this peculiarity. I have a class with a customizable function, as such:
#include<memory>
#include<functional>
#include<iostream>
class foo
{
private:
std::function<void()> action = nullptr;
public:
foo() = default;
void add_action(std::function<void()> lambda_expression)
{
action = lambda_expression;
}
void do_action()
{
action();
}
};
If in main I am to do the following
std::shared_ptr<foo> sp;
{
foo obj= foo();
sp = std::make_shared<foo>(obj);
obj.add_action([]() {std::cout << "hello world" << std::endl; });
}
sp->do_action();
It will invariable will cause the following error:" Unhandled exception at 0x75284192 in lambda expression.exe: Microsoft C++ exception: std::bad_function_call at memory location 0x0058F710."
And going into debug autos I can see that it read the action as "empty".
however, switching the order as such
obj.add_action([]() {std::cout << "hello world" << std::endl; });
sp = std::make_shared<foo>(obj);
or using the shared pointer to call add_action():
sp = std::make_shared<foo>(obj);
sp->add_action([]() {std::cout << "hello world" << std::endl; });
both work fine! (print "hello world")
Note: the normal pointer counterpart to this code does not work in either of these cases.
Does anyone know what could cause this? I am going to look into it but seems to rather subtle. If I find the reason why I shall post it on this thread. Thank you!
Working in Visual Studio 2019 version 16.4.3
foo obj= foo();
obj
is constructed by default constructor, so there is no a target in std::function
.
By
sp = std::make_shared<foo>(obj);
you create new instance of Foo
on a heap, whose lifetime is managed by smart pointer sp
. This newly created Foo
object has also no a target in std::function
, because obj
didn't have target when copying operation was performed. Foo(const Foo&)
just copied empty function.
After construction of sp
, these two Foo
instances are completely unrelated. By accessing sp
you don't modify obj
, and vice versa. So obj.add_action
could not update std::function
of Foo
constructed by shared_ptr
.
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.