di icon indicating copy to clipboard operation
di copied to clipboard

enforce deduction of const std::shared_ptr<T> &

Open SteRoh opened this issue 1 year ago • 2 comments

Context

In my case i want to share a logger instance through my classes therefore I pass some const std::shared_ptr<T>& into my classes.

Actually i cant change my constructor arguments, because i have to check if boost::di can be used non-invasive. Is there a way to enforce the right deduction of const std::shared_ptr<T>& ? Or how to handle this case?

auto log = std::make_shared<logger>();

auto injector = di::make_injector(
    di::bind<logger>().to(log),  
    di::bind<MyType>,     // needs a const std::shared_ptr<logger>&     
    di::bind<ANestedType> // needs a const std::shared_ptr<logger>&     
);

Expected Behavior

Each instance of my class is using the same logger.

Logoutput # 0 msg: MyType created
Logoutput # 1 msg: ANestedType created
Logoutput # 2 msg: log from ANestedType
Logoutput # 3 msg: log from MyType

Actual Behavior

The Logger which shall be passed by const std::shared_ptr<T>& is somehow dangling. In my example, it is obv not the same logger instance. Even the address sanitizer is complaining.

Logoutput # 0 msg: MyType created
Logoutput # 1843005592 msg: ANestedType created
Logoutput # 1843005593 msg: log from ANestedType
Logoutput # 1 msg: log from MyType

Steps to Reproduce the Problem

  1. https://godbolt.org/z/ezW4d56Ea
  2. remove the reference of the signature const std::shared_ptr<logger>& log

Specifications

  • Version: 1.3.0
  • Platform: any
  • Subsystem: any

SteRoh avatar Nov 23 '23 09:11 SteRoh

Note sure why scoped instance would not participate in the scope deduction for nested types but that seems the case. It might be easier to create a logger with di as well. That seems to work but not sure whether it fits your use case? https://godbolt.org/z/ejrT6hqK3

kris-jusiak avatar Nov 23 '23 10:11 kris-jusiak

Thx for the impressing fast response @krzysztof-jusiak :)

I stripped down the Problem to this simple example but my actual use case looks like this:

  1. LoggerFactory will be created once with some config files
  2. LoggerFactory is the only one who can create std::shared_ptr<logger>
  3. MyClass( const std::shared_ptr& logger)
  4. OtherClass( const std::shared_ptr& logger)

So within the injector i need one LoggerFactory and i thought i have to bind the const std::shared_ptr<logger>& to the create() Function of the LoggerFactory.

https://godbolt.org/z/YTbbo15rY I have no idea what to do inside the injector :)

Maybe there is an easy solution, but i could not find any examples which show this factory Use case.

SteRoh avatar Nov 23 '23 11:11 SteRoh