0

I have a main function that takes in a reference of a class object and try to update it via foo() and bar(), however, the bar() only allows to pass into a shared_ptr type. How can I guarantee it behaves as expected, assuming I am NOT allowed to modify the signature of bar().

void foo(MyStruct& s) { modifyS(s); } void bar(std::shared_ptr<MyStruct> s) { modifySAgain(s); } mainFunction(MyStruct& s) { foo(s); // bar(?) how should I do here such that s would be modified by bar() // bar(std::make_shared<Mystruct>(std::move(s)) ? } 
4
  • 1
    If you are allowed to change the signature of bar then why not just make it void bar(MyStruct& s) just like foo? Commented Oct 25, 2017 at 22:22
  • What behavior do you expect? You should be able to modify the object in both cases. Commented Oct 25, 2017 at 22:22
  • 3
    Either bar actually requires a std::shared_ptr to work correctly, or it only requires a MyStruct& to work correctly. If the latter, bar is written incorrectly and should be fixed. Commented Oct 25, 2017 at 22:24
  • 1
    Insofar as there is a low level technical solution to your problem, it likely involves enabled_shared_from_this. That said, I think the design is the issue here. If bar requires ownership, and mainFunction calls bar, then transitively mainFunction requires ownership too. But free functions should relatively rarely need to take ownership anyhow. Commented Oct 25, 2017 at 22:31

1 Answer 1

4

You could use a null-aliasing shared pointer:

bar(std::shared_ptr<MyStruct>(std::shared_ptr<MyStruct>(), &s)); 

The temporary shared pointer created in this call shares ownership with a null shared pointer, so it does nothing on destruction.

This is perhaps a bit of a hack.

Sign up to request clarification or add additional context in comments.

5 Comments

It may be hacky, but it's clever and I didn't even know this was possible. Nice. :-)
I'd appreciate a few words on how this 'hack' works.
@CaptainGiraffe: See constructor note 8 here. Basically, the outer constructor does reference counting for the first argument, but all other behaviors are in terms of the second argument. So it's managing a null pointer (the first argument), while exposing the second argument as if it were managing it. It's not safe if the function being called keeps its own copy though, since now it believes it can extend the lifetime of the value when that's not true (the lifetime of s is not tied to the shared pointer at all).
@CaptainGiraffe: No, you don't get to keep the pointer, that's the whole point. So no need for thanks.
Can't we just all share and get along!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.