boost-ext / di

C++14 Dependency Injection Library
https://boost-ext.github.io/di
1.14k stars 138 forks source link

std::unique_ptr + destructor = creatable constraint not satisfied #455

Closed victl closed 4 years ago

victl commented 4 years ago

Expected Behavior

The following code should compile:

#include <memory>
#include "di.hpp"

namespace di = boost::di;

class A
{
  std::unique_ptr<int> val_;

public:
  explicit A(std::unique_ptr<int> val) : val_(std::move(val)) {}
  ~A() {}
};

int main(int argc, const char *argv[])
{
  auto a = di::make_injector().create<A>();
}

Actual Behavior

Won't compile. However, if you comment out the destructor ~A(){}, then it compiles correctly.

Am I using std::unique_ptr incorrectly?

Complete error output from MSVC can be found HERE

Specifications

victl commented 4 years ago

I've figured out that when your class have unique_ptr, then a direct instance can't be created by boost-di, because the copy constructor is implicitly deleted. I suppose the create<A>() method is triggering a copy action somewhere inside. Everything making sense to me, except the fact that if you comment out the destructor it compiles.

For a workaround, I can create<std::unique_ptr<A>>() instead.

krzysztof-jusiak commented 4 years ago

Thanks, @victl. You are right, in that case defining the destructor requires the move.

You can do it by using rvalue ref or creating std::unique_ptr to avoid deleted copies.

int main() {
  [[maybe_unused]] auto&& a = di::make_injector().create<A&&>();
}

Full example here -> https://wandbox.org/permlink/V7Ap9C4YtfkFAGva

victl commented 4 years ago

@krzysztof-jusiak I have tried this method in my actual project with more complicated codes, I can't create rvalue references or unique_ptr either. Same problem: can't have destructor, compiles well without it. Can you explain why the destructor matters here?

kanstantsin-chernik commented 4 years ago

Hi. Check this out. I remember I have already answered this question. https://github.com/boost-experimental/di/issues/428