Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compilation error when using registerFactory: use of deleted function #126

Open
dfontenot opened this issue Sep 19, 2020 · 22 comments
Open

Comments

@dfontenot
Copy link

I'm running into an issue with Fruit 3.6.0 in which I run into a compilation error when using Fruit. I've distilled down my project into the following single file:

#include <iostream>
#include <functional>
#include <memory>
#include <utility>
#include "fruit/fruit.h"

using namespace fruit;
using namespace std;

class Qux {
public:
    void test() {
        cout << "Qux" << endl;
    }
};

class Bar {
public:
    virtual ~Bar() {}
    virtual void test() = 0;
};

class BarImpl : public Bar {
    unique_ptr<Qux> ptr_;
public:
    //BarImpl(unique_ptr<Qux>&& ptr) : ptr_(move(ptr)) {}
    BarImpl(unique_ptr<Qux> ptr) : ptr_(move(ptr)) {}
    BarImpl(BarImpl&& b) : ptr_(move(b.ptr_)) {}

    void test() override {
        cout << "BarImpl" << endl;
        ptr_->test();
    }
};

using BarFactory = function<unique_ptr<Bar>(unique_ptr<Qux>)>;

Component<BarFactory> getBarFactoryComponent() {
    return createComponent()
        .registerFactory<unique_ptr<Bar>(Assisted<unique_ptr<Qux> >)>(
                [](unique_ptr<Qux> ptr) {
                    BarImpl* b = new BarImpl(move(ptr));
                    return unique_ptr<Bar>(move(b));
                });
}

class Foo {
public:
    virtual void test() = 0;
    virtual ~Foo() {}
};

class FooImpl : public Foo {
    BarFactory& factory_;
public:
    INJECT(FooImpl(BarFactory& factory)) : factory_(factory) {}

    void test() override {
        cout << "FooImpl" << endl;
        auto bar_ptr = factory_(make_unique<Qux>());
        bar_ptr->test();
    }
};

Component<Foo> getFooComponent() {
    return createComponent().install(getBarFactoryComponent).bind<Foo, FooImpl>();
}

int main(int argc, char** argv) {
    Injector<Foo> injector(getFooComponent);
    Foo& instance = injector.get<Foo&>();

    instance.test();
    return 0;
}
In file included from /home/me/.conan/data/fruit/3.6.0/_/_/package/99fe6edc64c98b6ead2c33cb2b0bf89b59d7f7ce/include/fruit/component.h:25,
                 from /home/me/.conan/data/fruit/3.6.0/_/_/package/99fe6edc64c98b6ead2c33cb2b0bf89b59d7f7ce/include/fruit/fruit.h:27,
                 from main.cpp:5:
/home/me/.conan/data/fruit/3.6.0/_/_/package/99fe6edc64c98b6ead2c33cb2b0bf89b59d7f7ce/include/fruit/impl/component_functors.defn.h: In instantiation of ‘Arg fruit::impl::meta::GetAssistedArg<numAssistedBefore, numNonAssistedBefore, fruit::Assisted<Arg> >::operator()(InjectedArgsTuple&, UserProvidedArgsTuple&) [with InjectedArgsTuple = std::tuple<>; UserProvidedArgsTuple = std::tuple<std::unique_ptr<Qux, std::default_delete<Qux> >&>; int numAssistedBefore = 0; int numNonAssistedBefore = 0; Arg = std::unique_ptr<Qux>]’:
/home/me/.conan/data/fruit/3.6.0/_/_/package/99fe6edc64c98b6ead2c33cb2b0bf89b59d7f7ce/include/fruit/impl/component_functors.defn.h:88:24:   recursively required from ‘void fruit::impl::meta::Compose2ComponentFunctors::apply<F1, F2>::type::apply<Comp>::Op::operator()(fruit::impl::FixedSizeVector<fruit::impl::ComponentStorageEntry>&) [with Comp = fruit::impl::meta::Comp<fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<>, fruit::impl::meta::EmptyList>; F1 = fruit::impl::meta::ComponentFunctor::apply<fruit::impl::meta::RegisterFactory, fruit::impl::meta::Type<std::unique_ptr<Bar, std::default_delete<Bar> >(fruit::Assisted<std::unique_ptr<Qux, std::default_delete<Qux> > >)>, fruit::impl::meta::Type<getBarFactoryComponent()::<lambda(std::unique_ptr<Qux, std::default_delete<Qux> >)> > >::type; F2 = fruit::impl::meta::ProcessDeferredBindings]’
/home/me/.conan/data/fruit/3.6.0/_/_/package/99fe6edc64c98b6ead2c33cb2b0bf89b59d7f7ce/include/fruit/impl/component_functors.defn.h:88:24:   required from ‘void fruit::impl::meta::Compose2ComponentFunctors::apply<F1, F2>::type::apply<Comp>::Op::operator()(fruit::impl::FixedSizeVector<fruit::impl::ComponentStorageEntry>&) [with Comp = fruit::impl::meta::Comp<fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<>, fruit::impl::meta::EmptyList>; F1 = fruit::impl::meta::Compose2ComponentFunctors::apply<fruit::impl::meta::ComponentFunctor::apply<fruit::impl::meta::RegisterFactory, fruit::impl::meta::Type<std::unique_ptr<Bar, std::default_delete<Bar> >(fruit::Assisted<std::unique_ptr<Qux, std::default_delete<Qux> > >)>, fruit::impl::meta::Type<getBarFactoryComponent()::<lambda(std::unique_ptr<Qux, std::default_delete<Qux> >)> > >::type, fruit::impl::meta::ProcessDeferredBindings>::type; F2 = fruit::impl::meta::ComponentFunctor::apply<fruit::impl::meta::ConvertComponent, fruit::impl::meta::Comp<fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<fruit::impl::meta::Type<std::function<std::unique_ptr<Bar, std::default_delete<Bar> >(std::unique_ptr<Qux, std::default_delete<Qux> >)> > >, fruit::impl::meta::Vector<fruit::impl::meta::Type<std::function<std::unique_ptr<Bar, std::default_delete<Bar> >(std::unique_ptr<Qux, std::default_delete<Qux> >)> > >, fruit::impl::meta::Vector<fruit::impl::meta::Pair<fruit::impl::meta::Type<std::function<std::unique_ptr<Bar, std::default_delete<Bar> >(std::unique_ptr<Qux, std::default_delete<Qux> >)> >, fruit::impl::meta::Vector<> > >, fruit::impl::meta::Vector<>, fruit::impl::meta::EmptyList> >::type]’
/home/me/.conan/data/fruit/3.6.0/_/_/package/99fe6edc64c98b6ead2c33cb2b0bf89b59d7f7ce/include/fruit/impl/component.defn.h:66:7:   required from ‘fruit::Component<Types>::Component(fruit::PartialComponent<Bindings ...>&&) [with Bindings = {fruit::impl::RegisterFactory<std::unique_ptr<Bar, std::default_delete<Bar> >(fruit::Assisted<std::unique_ptr<Qux, std::default_delete<Qux> > >), getBarFactoryComponent()::<lambda(std::unique_ptr<Qux, std::default_delete<Qux> >)> >}; Params = {std::function<std::unique_ptr<Bar, std::default_delete<Bar> >(std::unique_ptr<Qux, std::default_delete<Qux> >)>}]’
main.cpp:49:18:   required from here
/home/me/.conan/data/fruit/3.6.0/_/_/package/99fe6edc64c98b6ead2c33cb2b0bf89b59d7f7ce/include/fruit/impl/component_functors.defn.h:405:58: error: use of deleted function ‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = Qux; _Dp = std::default_delete<Qux>]’
  405 |     return std::get<numAssistedBefore>(user_provided_args);
      |                                                          ^
In file included from /usr/include/c++/9/memory:80,
                 from main.cpp:3:
/usr/include/c++/9/bits/unique_ptr.h:414:7: note: declared here
  414 |       unique_ptr(const unique_ptr&) = delete;
      |       ^~~~~~~~~~

I also attempted to de-fruit-ify the library the best I could, and I was able to get a working binary from it:


#include <iostream>
#include <functional>
#include <memory>
#include <utility>

using namespace std;

class Qux {
public:
    void test() {
        cout << "Qux" << endl;
    }
};

class Bar {
public:
    virtual ~Bar() {}
    virtual void test() = 0;
};

class BarImpl : public Bar {
    unique_ptr<Qux> ptr_;
public:
    BarImpl(unique_ptr<Qux> ptr) : ptr_(move(ptr)) {}
    BarImpl(BarImpl&& b) : ptr_(move(b.ptr_)) {}

    void test() override {
        cout << "BarImpl" << endl;
        ptr_->test();
    }
};

using BarFactory = function<unique_ptr<Bar>(unique_ptr<Qux>)>;

BarFactory getBarFactory() {
    return [](unique_ptr<Qux> ptr) {
        BarImpl* b = new BarImpl(move(ptr));
        return unique_ptr<Bar>(move(b));
    };
}

class Foo {
public:
    virtual void test() = 0;
    virtual ~Foo() {}
};

class FooImpl : public Foo {
    BarFactory& factory_;
public:
    FooImpl(BarFactory& factory) : factory_(factory) {}

    void test() override {
        cout << "FooImpl" << endl;
        auto bar_ptr = factory_(make_unique<Qux>());
        bar_ptr->test();
    }
};

int main(int argc, char** argv) {

    BarFactory factory = getBarFactory();
    Foo* instance = new FooImpl(factory);

    instance->test();
    return 0;
}

Would you be able to provide any guidance as to if I'm misusing registerFactory? Or was there an error in my code that was not properly translated when it was converted into non-fruit code? My c++ is definitely a rusty, but it seems as though the lambda that the compiler is complaining about is the same between both versions.

@tt4g
Copy link
Contributor

tt4g commented Sep 19, 2020

In getBarFactoryComponent(), std::unique_ptr<Bar>(std::move(b)) is cannot compile, Should use std::make_unique<Bar>(std::move(b)).

Component<BarFactory> getBarFactoryComponent() {
    return createComponent()
+        .bind<Bar, BarImpl>()
        .registerFactory<unique_ptr<Bar>(Assisted<unique_ptr<Qux> >)>(
                [](unique_ptr<Qux> ptr) {
                    BarImpl* b = new BarImpl(move(ptr));
-                    return unique_ptr<Bar>(move(b));
+                    return std::make_unique<Bar>(move(b));
                });
}

@dfontenot
Copy link
Author

dfontenot commented Sep 19, 2020

@tt4g thanks, gave that a try. However, another error was introduced. It looks like std::make_unique used std::forward which caused issues since Bar is abstract.

In file included from /usr/include/c++/9/memory:80,
                 from main.cpp:3:
/usr/include/c++/9/bits/unique_ptr.h: In instantiation of ‘typename std::_MakeUniq<_Tp>::__single_object std::make_unique(_Args&& ...) [with _Tp = Bar; _Args = {BarImpl*}; typename std::_MakeUniq<_Tp>::__single_object = std::unique_ptr<Bar>]’:
main.cpp:47:52:   required from here
/usr/include/c++/9/bits/unique_ptr.h:857:30: error: invalid new-expression of abstract class type ‘Bar’
  857 |     { return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...)); }
      |                              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
main.cpp:17:7: note:   because the following virtual functions are pure within ‘Bar’:
   17 | class Bar {
      |       ^~~
main.cpp:20:18: note: 	‘virtual void Bar::test()’
   20 |     virtual void test() = 0;
      |                  ^~~~
In file included from /home/me/.conan/data/fruit/3.6.0/_/_/package/99fe6edc64c98b6ead2c33cb2b0bf89b59d7f7ce/include/fruit/component.h:25,
                 from /home/me/.conan/data/fruit/3.6.0/_/_/package/99fe6edc64c98b6ead2c33cb2b0bf89b59d7f7ce/include/fruit/fruit.h:27,
                 from main.cpp:5:
/home/me/.conan/data/fruit/3.6.0/_/_/package/99fe6edc64c98b6ead2c33cb2b0bf89b59d7f7ce/include/fruit/impl/component_functors.defn.h: In instantiation of ‘Arg fruit::impl::meta::GetAssistedArg<numAssistedBefore, numNonAssistedBefore, fruit::Assisted<Arg> >::operator()(InjectedArgsTuple&, UserProvidedArgsTuple&) [with InjectedArgsTuple = std::tuple<>; UserProvidedArgsTuple = std::tuple<std::unique_ptr<Qux, std::default_delete<Qux> >&>; int numAssistedBefore = 0; int numNonAssistedBefore = 0; Arg = std::unique_ptr<Qux>]’:
/home/me/.conan/data/fruit/3.6.0/_/_/package/99fe6edc64c98b6ead2c33cb2b0bf89b59d7f7ce/include/fruit/impl/component_functors.defn.h:452:95:   required from ‘void fruit::impl::meta::RegisterFactoryHelper::apply<Comp, DecoratedSignature, Lambda, fruit::impl::meta::Type<NakedC(NakedUserProvidedArgs ...)>, fruit::impl::meta::Type<NakedC(NakedAllArgs ...)>, fruit::impl::meta::Vector<InjectedAnnotatedArgs ...>, fruit::impl::meta::Vector<fruit::impl::meta::Type<NakedInjectedArgs>...>, fruit::impl::meta::Vector<Indexes ...> >::Op::operator()(fruit::impl::FixedSizeVector<fruit::impl::ComponentStorageEntry>&) [with Comp = fruit::impl::meta::Comp<fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<fruit::impl::meta::Pair<fruit::impl::meta::Type<Bar>, fruit::impl::meta::Type<BarImpl> > >, fruit::impl::meta::EmptyList>; DecoratedSignature = fruit::impl::meta::Type<std::unique_ptr<Bar>(fruit::Assisted<std::unique_ptr<Qux> >)>; Lambda = fruit::impl::meta::Type<getBarFactoryComponent()::<lambda(std::unique_ptr<Qux>)> >; NakedC = std::unique_ptr<Bar>; NakedUserProvidedArgs = {std::unique_ptr<Qux, std::default_delete<Qux> >}; NakedAllArgs = {std::unique_ptr<Qux, std::default_delete<Qux> >}; InjectedAnnotatedArgs = {}; NakedInjectedArgs = {}; Indexes = {fruit::impl::meta::Int<0>}]’
/home/me/.conan/data/fruit/3.6.0/_/_/package/99fe6edc64c98b6ead2c33cb2b0bf89b59d7f7ce/include/fruit/impl/component_functors.defn.h:88:24:   recursively required from ‘void fruit::impl::meta::Compose2ComponentFunctors::apply<F1, F2>::type::apply<Comp>::Op::operator()(fruit::impl::FixedSizeVector<fruit::impl::ComponentStorageEntry>&) [with Comp = fruit::impl::meta::Comp<fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<>, fruit::impl::meta::EmptyList>; F1 = fruit::impl::meta::Compose2ComponentFunctors::apply<fruit::impl::meta::ComponentFunctor::apply<fruit::impl::meta::AddDeferredInterfaceBinding, fruit::impl::meta::Type<Bar>, fruit::impl::meta::Type<BarImpl> >::type, fruit::impl::meta::ComponentFunctor::apply<fruit::impl::meta::RegisterFactory, fruit::impl::meta::Type<std::unique_ptr<Bar, std::default_delete<Bar> >(fruit::Assisted<std::unique_ptr<Qux, std::default_delete<Qux> > >)>, fruit::impl::meta::Type<getBarFactoryComponent()::<lambda(std::unique_ptr<Qux, std::default_delete<Qux> >)> > >::type>::type; F2 = fruit::impl::meta::ProcessDeferredBindings]’
/home/me/.conan/data/fruit/3.6.0/_/_/package/99fe6edc64c98b6ead2c33cb2b0bf89b59d7f7ce/include/fruit/impl/component_functors.defn.h:88:24:   required from ‘void fruit::impl::meta::Compose2ComponentFunctors::apply<F1, F2>::type::apply<Comp>::Op::operator()(fruit::impl::FixedSizeVector<fruit::impl::ComponentStorageEntry>&) [with Comp = fruit::impl::meta::Comp<fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<>, fruit::impl::meta::EmptyList>; F1 = fruit::impl::meta::Compose2ComponentFunctors::apply<fruit::impl::meta::Compose2ComponentFunctors::apply<fruit::impl::meta::ComponentFunctor::apply<fruit::impl::meta::AddDeferredInterfaceBinding, fruit::impl::meta::Type<Bar>, fruit::impl::meta::Type<BarImpl> >::type, fruit::impl::meta::ComponentFunctor::apply<fruit::impl::meta::RegisterFactory, fruit::impl::meta::Type<std::unique_ptr<Bar, std::default_delete<Bar> >(fruit::Assisted<std::unique_ptr<Qux, std::default_delete<Qux> > >)>, fruit::impl::meta::Type<getBarFactoryComponent()::<lambda(std::unique_ptr<Qux, std::default_delete<Qux> >)> > >::type>::type, fruit::impl::meta::ProcessDeferredBindings>::type; F2 = fruit::impl::meta::ComponentFunctor::apply<fruit::impl::meta::ConvertComponent, fruit::impl::meta::Comp<fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<fruit::impl::meta::Type<std::function<std::unique_ptr<Bar, std::default_delete<Bar> >(std::unique_ptr<Qux, std::default_delete<Qux> >)> > >, fruit::impl::meta::Vector<fruit::impl::meta::Type<std::function<std::unique_ptr<Bar, std::default_delete<Bar> >(std::unique_ptr<Qux, std::default_delete<Qux> >)> > >, fruit::impl::meta::Vector<fruit::impl::meta::Pair<fruit::impl::meta::Type<std::function<std::unique_ptr<Bar, std::default_delete<Bar> >(std::unique_ptr<Qux, std::default_delete<Qux> >)> >, fruit::impl::meta::Vector<> > >, fruit::impl::meta::Vector<>, fruit::impl::meta::EmptyList> >::type]’
/home/me/.conan/data/fruit/3.6.0/_/_/package/99fe6edc64c98b6ead2c33cb2b0bf89b59d7f7ce/include/fruit/impl/component.defn.h:66:7:   required from ‘fruit::Component<Types>::Component(fruit::PartialComponent<Bindings ...>&&) [with Bindings = {fruit::impl::RegisterFactory<std::unique_ptr<Bar, std::default_delete<Bar> >(fruit::Assisted<std::unique_ptr<Qux, std::default_delete<Qux> > >), getBarFactoryComponent()::<lambda(std::unique_ptr<Qux, std::default_delete<Qux> >)> >, fruit::impl::Bind<Bar, BarImpl>}; Params = {std::function<std::unique_ptr<Bar, std::default_delete<Bar> >(std::unique_ptr<Qux, std::default_delete<Qux> >)>}]’
main.cpp:52:18:   required from here
/home/me/.conan/data/fruit/3.6.0/_/_/package/99fe6edc64c98b6ead2c33cb2b0bf89b59d7f7ce/include/fruit/impl/component_functors.defn.h:405:58: error: use of deleted function ‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = Qux; _Dp = std::default_delete<Qux>]’
  405 |     return std::get<numAssistedBefore>(user_provided_args);
      |                                                          ^
In file included from /usr/include/c++/9/memory:80,
                 from main.cpp:3:
/usr/include/c++/9/bits/unique_ptr.h:414:7: note: declared here
  414 |       unique_ptr(const unique_ptr&) = delete;
      |

@tt4g
Copy link
Contributor

tt4g commented Sep 19, 2020

Sorry. I was wrong too.
Replace return std::make_unique<Bar>(move(b)); with return std::make_unique<BarImpl>(move(ptr));

Component<BarFactory> getBarFactoryComponent() {
    return createComponent()
        .bind<Bar, BarImpl>()
        .registerFactory<unique_ptr<Bar>(Assisted<unique_ptr<Qux> >)>(
                [](unique_ptr<Qux> ptr) {
-                    BarImpl* b = new BarImpl(move(ptr));
-                    return unique_ptr<Bar>(move(b));
-                    return std::make_unique<Bar>(move(b));
+                    return std::make_unique<BarImpl>(move(ptr));
                });
}

@dfontenot
Copy link
Author

With that change, looks like the standard library errors cleared up. However, some static_asserts from Fruit are now failing.

In file included from /home/me/.conan/data/fruit/3.6.0/_/_/package/99fe6edc64c98b6ead2c33cb2b0bf89b59d7f7ce/include/fruit/fruit.h:25,
                 from main.cpp:5:
/home/me/.conan/data/fruit/3.6.0/_/_/package/99fe6edc64c98b6ead2c33cb2b0bf89b59d7f7ce/include/fruit/impl/injection_errors.h: In instantiation of ‘struct fruit::impl::FunctorSignatureDoesNotMatchError<std::unique_ptr<Bar>(std::unique_ptr<Qux>), std::unique_ptr<BarImpl, std::default_delete<BarImpl> >(std::unique_ptr<Qux>)>’:
/home/me/.conan/data/fruit/3.6.0/_/_/package/99fe6edc64c98b6ead2c33cb2b0bf89b59d7f7ce/include/fruit/impl/component.defn.h:234:55:   required from ‘fruit::PartialComponent<fruit::impl::RegisterFactory<DecoratedSignature, Factory>, Bindings ...> fruit::PartialComponent<Bindings>::registerFactory(Lambda) [with DecoratedSignature = std::unique_ptr<Bar>(fruit::Assisted<std::unique_ptr<Qux> >); Factory = getBarFactoryComponent()::<lambda(std::unique_ptr<Qux>)>; Bindings = {fruit::impl::Bind<Bar, BarImpl>}]’
main.cpp:53:18:   required from here
/home/me/.conan/data/fruit/3.6.0/_/_/package/99fe6edc64c98b6ead2c33cb2b0bf89b59d7f7ce/include/fruit/impl/injection_errors.h:242:49: error: static assertion failed: Unexpected functor signature (it should be the same as ExpectedSignature minus any Assisted types).
  242 |   static_assert(AlwaysFalse<ExpectedSignature>::value,
      |                                                 ^~~~~
In file included from /home/me/.conan/data/fruit/3.6.0/_/_/package/99fe6edc64c98b6ead2c33cb2b0bf89b59d7f7ce/include/fruit/component.h:1080,
                 from /home/me/.conan/data/fruit/3.6.0/_/_/package/99fe6edc64c98b6ead2c33cb2b0bf89b59d7f7ce/include/fruit/fruit.h:27,
                 from main.cpp:5:
/home/me/.conan/data/fruit/3.6.0/_/_/package/99fe6edc64c98b6ead2c33cb2b0bf89b59d7f7ce/include/fruit/impl/component.defn.h: In instantiation of ‘fruit::Component<Types>::Component(fruit::PartialComponent<Bindings ...>&&) [with Bindings = {fruit::impl::RegisterFactory<std::unique_ptr<Bar, std::default_delete<Bar> >(fruit::Assisted<std::unique_ptr<Qux, std::default_delete<Qux> > >), getBarFactoryComponent()::<lambda(std::unique_ptr<Qux, std::default_delete<Qux> >)> >, fruit::impl::Bind<Bar, BarImpl>}; Params = {std::function<std::unique_ptr<Bar, std::default_delete<Bar> >(std::unique_ptr<Qux, std::default_delete<Qux> >)>}]’:
main.cpp:53:18:   required from here
/home/me/.conan/data/fruit/3.6.0/_/_/package/99fe6edc64c98b6ead2c33cb2b0bf89b59d7f7ce/include/fruit/impl/component.defn.h:60:92: error: no type named ‘Result’ in ‘fruit::impl::meta::OpForComponent<fruit::impl::RegisterFactory<std::unique_ptr<Bar, std::default_delete<Bar> >(fruit::Assisted<std::unique_ptr<Qux, std::default_delete<Qux> > >), getBarFactoryComponent()::<lambda(std::unique_ptr<Qux, std::default_delete<Qux> >)> >, fruit::impl::Bind<Bar, BarImpl> >::ConvertTo<fruit::impl::meta::Comp<fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<fruit::impl::meta::Type<std::function<std::unique_ptr<Bar, std::default_delete<Bar> >(std::unique_ptr<Qux, std::default_delete<Qux> >)> > >, fruit::impl::meta::Vector<fruit::impl::meta::Type<std::function<std::unique_ptr<Bar, std::default_delete<Bar> >(std::unique_ptr<Qux, std::default_delete<Qux> >)> > >, fruit::impl::meta::Vector<fruit::impl::meta::Pair<fruit::impl::meta::Type<std::function<std::unique_ptr<Bar, std::default_delete<Bar> >(std::unique_ptr<Qux, std::default_delete<Qux> >)> >, fruit::impl::meta::Vector<> > >, fruit::impl::meta::Vector<>, fruit::impl::meta::EmptyList> >’ {aka ‘struct fruit::impl::meta::Error<fruit::impl::FunctorSignatureDoesNotMatchErrorTag, std::unique_ptr<Bar, std::default_delete<Bar> >(std::unique_ptr<Qux, std::default_delete<Qux> >), std::unique_ptr<BarImpl, std::default_delete<BarImpl> >(std::unique_ptr<Qux, std::default_delete<Qux> >)>’}
   60 |       fruit::impl::meta::Eval<fruit::impl::meta::CheckNoLoopInDeps(typename Op::Result)>>::type();
      |                                                                                            ^~~~~~
/home/me/.conan/data/fruit/3.6.0/_/_/package/99fe6edc64c98b6ead2c33cb2b0bf89b59d7f7ce/include/fruit/impl/component.defn.h:63:76: error: ‘using Op = fruit::impl::meta::OpForComponent<fruit::impl::RegisterFactory<std::unique_ptr<Bar, std::default_delete<Bar> >(fruit::Assisted<std::unique_ptr<Qux, std::default_delete<Qux> > >), getBarFactoryComponent()::<lambda(std::unique_ptr<Qux, std::default_delete<Qux> >)> >, fruit::impl::Bind<Bar, BarImpl> >::ConvertTo<fruit::impl::meta::Comp<fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<fruit::impl::meta::Type<std::function<std::unique_ptr<Bar, std::default_delete<Bar> >(std::unique_ptr<Qux, std::default_delete<Qux> >)> > >, fruit::impl::meta::Vector<fruit::impl::meta::Type<std::function<std::unique_ptr<Bar, std::default_delete<Bar> >(std::unique_ptr<Qux, std::default_delete<Qux> >)> > >, fruit::impl::meta::Vector<fruit::impl::meta::Pair<fruit::impl::meta::Type<std::function<std::unique_ptr<Bar, std::default_delete<Bar> >(std::unique_ptr<Qux, std::default_delete<Qux> >)> >, fruit::impl::meta::Vector<> > >, fruit::impl::meta::Vector<>, fruit::impl::meta::EmptyList> >’ {aka ‘struct fruit::impl::meta::Error<fruit::impl::FunctorSignatureDoesNotMatchErrorTag, std::unique_ptr<Bar, std::default_delete<Bar> >(std::unique_ptr<Qux, std::default_delete<Qux> >), std::unique_ptr<BarImpl, std::default_delete<BarImpl> >(std::unique_ptr<Qux, std::default_delete<Qux> >)>’} has no member named ‘numEntries’
   63 |   std::size_t num_entries = partial_component.storage.numBindings() + Op().numEntries();
      |                                                                       ~~~~~^~~~~~~~~~
/home/me/.conan/data/fruit/3.6.0/_/_/package/99fe6edc64c98b6ead2c33cb2b0bf89b59d7f7ce/include/fruit/impl/component.defn.h:66:7: error: no match for call to ‘(Op {aka fruit::impl::meta::Error<fruit::impl::FunctorSignatureDoesNotMatchErrorTag, std::unique_ptr<Bar, std::default_delete<Bar> >(std::unique_ptr<Qux, std::default_delete<Qux> >), std::unique_ptr<BarImpl, std::default_delete<BarImpl> >(std::unique_ptr<Qux, std::default_delete<Qux> >)>}) (fruit::impl::FixedSizeVector<fruit::impl::ComponentStorageEntry>&)’
   66 |   Op()(entries);
      |   ~~~~^~~~~~~~~
In file included from /home/me/.conan/data/fruit/3.6.0/_/_/package/99fe6edc64c98b6ead2c33cb2b0bf89b59d7f7ce/include/fruit/impl/component_storage/partial_component_storage.h:47,
                 from /home/me/.conan/data/fruit/3.6.0/_/_/package/99fe6edc64c98b6ead2c33cb2b0bf89b59d7f7ce/include/fruit/component.h:27,
                 from /home/me/.conan/data/fruit/3.6.0/_/_/package/99fe6edc64c98b6ead2c33cb2b0bf89b59d7f7ce/include/fruit/fruit.h:27,
                 from main.cpp:5:
/home/me/.conan/data/fruit/3.6.0/_/_/package/99fe6edc64c98b6ead2c33cb2b0bf89b59d7f7ce/include/fruit/impl/component_storage/partial_component_storage.defn.h:321:8: warning: ‘void fruit::impl::PartialComponentStorage<fruit::impl::RegisterFactory<DecoratedSignature, Lambda>, PreviousBindings ...>::addBindings(fruit::impl::FixedSizeVector<fruit::impl::ComponentStorageEntry>&) const [with DecoratedSignature = std::unique_ptr<Bar>(fruit::Assisted<std::unique_ptr<Qux> >); Lambda = getBarFactoryComponent()::<lambda(std::unique_ptr<Qux>)>; PreviousBindings = {fruit::impl::Bind<Bar, BarImpl>}]’ used but never defined
  321 |   void addBindings(FixedSizeVector<ComponentStorageEntry>& entries) const {
      |        ^~~~~~~~~~~
In file included from /home/me/.conan/data/fruit/3.6.0/_/_/package/99fe6edc64c98b6ead2c33cb2b0bf89b59d7f7ce/include/fruit/component.h:1080,
                 from /home/me/.conan/data/fruit/3.6.0/_/_/package/99fe6edc64c98b6ead2c33cb2b0bf89b59d7f7ce/include/fruit/fruit.h:27,
                 from main.cpp:5:
/home/me/.conan/data/fruit/3.6.0/_/_/package/99fe6edc64c98b6ead2c33cb2b0bf89b59d7f7ce/include/fruit/impl/component.defn.h:240:8: warning: ‘fruit::PartialComponent<Bindings>::PartialComponent(fruit::impl::PartialComponentStorage<Bindings ...>) [with Bindings = {fruit::impl::RegisterFactory<std::unique_ptr<Bar, std::default_delete<Bar> >(fruit::Assisted<std::unique_ptr<Qux, std::default_delete<Qux> > >), getBarFactoryComponent()::<lambda(std::unique_ptr<Qux, std::default_delete<Qux> >)> >, fruit::impl::Bind<Bar, BarImpl>}]’ used but never defined
  240 | inline PartialComponent<Bindings...>::PartialComponent(fruit::impl::PartialComponentStorage<Bindings...> storage)
      |        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /home/me/.conan/data/fruit/3.6.0/_/_/package/99fe6edc64c98b6ead2c33cb2b0bf89b59d7f7ce/include/fruit/impl/component_storage/partial_component_storage.h:47,
                 from /home/me/.conan/data/fruit/3.6.0/_/_/package/99fe6edc64c98b6ead2c33cb2b0bf89b59d7f7ce/include/fruit/component.h:27,
                 from /home/me/.conan/data/fruit/3.6.0/_/_/package/99fe6edc64c98b6ead2c33cb2b0bf89b59d7f7ce/include/fruit/fruit.h:27,
                 from main.cpp:5:
/home/me/.conan/data/fruit/3.6.0/_/_/package/99fe6edc64c98b6ead2c33cb2b0bf89b59d7f7ce/include/fruit/impl/component_storage/partial_component_storage.defn.h:318:3: warning: ‘fruit::impl::PartialComponentStorage<fruit::impl::RegisterFactory<DecoratedSignature, Lambda>, PreviousBindings ...>::PartialComponentStorage(fruit::impl::PartialComponentStorage<PreviousBindings ...>&) [with DecoratedSignature = std::unique_ptr<Bar>(fruit::Assisted<std::unique_ptr<Qux> >); Lambda = getBarFactoryComponent()::<lambda(std::unique_ptr<Qux>)>; PreviousBindings = {fruit::impl::Bind<Bar, BarImpl>}]’ used but never defined
  318 |   PartialComponentStorage(PartialComponentStorage<PreviousBindings...>& previous_storage) // NOLINT(google-explicit-constructor)
      |   ^~~~~~~~~~~~~~~~~~~~~~~

@tt4g
Copy link
Contributor

tt4g commented Sep 20, 2020

/home/me/.conan/data/fruit/3.6.0/_/_/package/99fe6edc64c98b6ead2c33cb2b0bf89b59d7f7ce/include/fruit/impl/injection_errors.h: In instantiation of ‘struct fruit::impl::FunctorSignatureDoesNotMatchError<std::unique_ptr<Bar>(std::unique_ptr<Qux>), std::unique_ptr<BarImpl, std::default_delete<BarImpl> >(std::unique_ptr<Qux>)>’:
/home/me/.conan/data/fruit/3.6.0/_/_/package/99fe6edc64c98b6ead2c33cb2b0bf89b59d7f7ce/include/fruit/impl/component.defn.h:234:55:   required from ‘fruit::PartialComponent<fruit::impl::RegisterFactory<DecoratedSignature, Factory>, Bindings ...> fruit::PartialComponent<Bindings>::registerFactory(Lambda) [with DecoratedSignature = std::unique_ptr<Bar>(fruit::Assisted<std::unique_ptr<Qux> >); Factory = getBarFactoryComponent()::<lambda(std::unique_ptr<Qux>)>; Bindings = {fruit::impl::Bind<Bar, BarImpl>}]’

Apparently you have to tell fruit exactly what type the factory function will return.

@parameterized.parameters([
('Scaler',
'ScalerImpl',
'std::unique_ptr<ScalerImpl>',
'std::function<std::unique_ptr<Scaler>(double)>'),
('fruit::Annotated<Annotation1, Scaler>',
'fruit::Annotated<Annotation2, ScalerImpl>',
'fruit::Annotated<Annotation2, std::unique_ptr<ScalerImpl>>',
'fruit::Annotated<Annotation1, std::function<std::unique_ptr<Scaler>(double)>>'),
])
def test_register_factory_for_unique_pointer_returning_invalid_unique_ptr_ok(self, ScalerAnnot, ScalerImplAnnot, ScalerImplPtrAnnot, ScalerFactoryAnnot):
source = '''
struct Scaler {
virtual double scale(double x) = 0;
virtual ~Scaler() = default;
};
struct ScalerImpl : public Scaler {
private:
double factor;
public:
ScalerImpl(double factor)
: factor(factor) {
}
double scale(double x) override {
return x * factor;
}
};
using ScalerFactory = std::function<std::unique_ptr<Scaler>(double)>;
fruit::Component<ScalerFactoryAnnot> getScalerComponent() {
return fruit::createComponent()
.bind<ScalerAnnot, ScalerImplAnnot>()
.registerFactory<ScalerImplPtrAnnot(fruit::Assisted<double>)>(
[](double) {
return std::unique_ptr<ScalerImpl>(nullptr);
});
}
int main() {
fruit::Injector<ScalerFactoryAnnot> injector(getScalerComponent);
ScalerFactory scalerFactory = injector.get<ScalerFactoryAnnot>();
std::unique_ptr<Scaler> scaler = scalerFactory(12.1);
Assert(scaler.get() == nullptr);
}
'''
expect_success(
COMMON_DEFINITIONS,
source,
locals())

Try specifying std::unique_ptr<BarImpl> as the template argument for registerFactory<T>().

Component<BarFactory> getBarFactoryComponent() {
    return createComponent()
        .bind<Bar, BarImpl>()
-        .registerFactory<unique_ptr<Bar>(Assisted<unique_ptr<Qux>>)>(
+        .registerFactory<unique_ptr<BarImpl>(Assisted<unique_ptr<Qux>>)>(
                [](unique_ptr<Qux> ptr) {
                    return std::make_unique<BarImpl>(move(ptr));
                });
}

@dfontenot
Copy link
Author

With that newest change to specify the template argument as std::unique_ptr<BarImpl>, I am now back to getting use of deleted functions errors.

In file included from /home/me/.conan/data/fruit/3.6.0/_/_/package/99fe6edc64c98b6ead2c33cb2b0bf89b59d7f7ce/include/fruit/component.h:25,
                 from /home/me/.conan/data/fruit/3.6.0/_/_/package/99fe6edc64c98b6ead2c33cb2b0bf89b59d7f7ce/include/fruit/fruit.h:27,
                 from main.cpp:5:
/home/me/.conan/data/fruit/3.6.0/_/_/package/99fe6edc64c98b6ead2c33cb2b0bf89b59d7f7ce/include/fruit/impl/component_functors.defn.h: In instantiation of ‘void fruit::impl::meta::AutoRegisterFactoryHelper::apply<Comp, TargetRequirements, TargetNonConstRequirements, AnnotatedC, unused1, unused2, fruit::impl::meta::Type<std::unique_ptr<NakedI> >, AnnotatedSignature, Args ...>::Op::operator()(fruit::impl::FixedSizeVector<fruit::impl::ComponentStorageEntry>&) [with Comp = fruit::impl::meta::Comp<fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<fruit::impl::meta::Type<std::function<std::unique_ptr<BarImpl, std::default_delete<BarImpl> >(std::unique_ptr<Qux, std::default_delete<Qux> >)> > >, fruit::impl::meta::Vector<fruit::impl::meta::Type<std::function<std::unique_ptr<BarImpl, std::default_delete<BarImpl> >(std::unique_ptr<Qux, std::default_delete<Qux> >)> > >, fruit::impl::meta::Vector<fruit::impl::meta::Pair<fruit::impl::meta::Type<std::function<std::unique_ptr<BarImpl, std::default_delete<BarImpl> >(std::unique_ptr<Qux, std::default_delete<Qux> >)> >, fruit::impl::meta::Vector<> > >, fruit::impl::meta::Vector<fruit::impl::meta::Pair<fruit::impl::meta::Type<Bar>, fruit::impl::meta::Type<BarImpl> > >, fruit::impl::meta::EmptyList>; TargetRequirements = fruit::impl::meta::Vector<>; TargetNonConstRequirements = fruit::impl::meta::Vector<>; AnnotatedC = fruit::impl::meta::Type<BarImpl>; unused1 = fruit::impl::meta::Bool<false>; unused2 = fruit::impl::meta::Bool<true>; NakedI = Bar; AnnotatedSignature = fruit::impl::meta::Type<std::unique_ptr<Bar>(std::unique_ptr<Qux>)>; Args = {fruit::impl::meta::Type<std::unique_ptr<Qux, std::default_delete<Qux> > >}]’:
/home/me/.conan/data/fruit/3.6.0/_/_/package/99fe6edc64c98b6ead2c33cb2b0bf89b59d7f7ce/include/fruit/impl/component_functors.defn.h:88:24:   required from ‘void fruit::impl::meta::Compose2ComponentFunctors::apply<F1, F2>::type::apply<Comp>::Op::operator()(fruit::impl::FixedSizeVector<fruit::impl::ComponentStorageEntry>&) [with Comp = fruit::impl::meta::Comp<fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<fruit::impl::meta::Type<std::function<std::unique_ptr<BarImpl, std::default_delete<BarImpl> >(std::unique_ptr<Qux, std::default_delete<Qux> >)> > >, fruit::impl::meta::Vector<fruit::impl::meta::Type<std::function<std::unique_ptr<BarImpl, std::default_delete<BarImpl> >(std::unique_ptr<Qux, std::default_delete<Qux> >)> > >, fruit::impl::meta::Vector<fruit::impl::meta::Pair<fruit::impl::meta::Type<std::function<std::unique_ptr<BarImpl, std::default_delete<BarImpl> >(std::unique_ptr<Qux, std::default_delete<Qux> >)> >, fruit::impl::meta::Vector<> > >, fruit::impl::meta::Vector<fruit::impl::meta::Pair<fruit::impl::meta::Type<Bar>, fruit::impl::meta::Type<BarImpl> > >, fruit::impl::meta::EmptyList>; F1 = fruit::impl::meta::ComponentFunctor::apply<fruit::impl::meta::EnsureProvidedType, fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<>, fruit::impl::meta::Type<std::function<std::unique_ptr<Bar, std::default_delete<Bar> >(std::unique_ptr<Qux, std::default_delete<Qux> >)> >, fruit::impl::meta::Bool<true> >::type; F2 = fruit::impl::meta::ComponentFunctorIdentity]’
/home/me/.conan/data/fruit/3.6.0/_/_/package/99fe6edc64c98b6ead2c33cb2b0bf89b59d7f7ce/include/fruit/impl/component_functors.defn.h:87:24:   required from ‘void fruit::impl::meta::Compose2ComponentFunctors::apply<F1, F2>::type::apply<Comp>::Op::operator()(fruit::impl::FixedSizeVector<fruit::impl::ComponentStorageEntry>&) [with Comp = fruit::impl::meta::Comp<fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<>, fruit::impl::meta::EmptyList>; F1 = fruit::impl::meta::Compose2ComponentFunctors::apply<fruit::impl::meta::Compose2ComponentFunctors::apply<fruit::impl::meta::ComponentFunctor::apply<fruit::impl::meta::AddDeferredInterfaceBinding, fruit::impl::meta::Type<Bar>, fruit::impl::meta::Type<BarImpl> >::type, fruit::impl::meta::ComponentFunctor::apply<fruit::impl::meta::RegisterFactory, fruit::impl::meta::Type<std::unique_ptr<BarImpl, std::default_delete<BarImpl> >(fruit::Assisted<std::unique_ptr<Qux, std::default_delete<Qux> > >)>, fruit::impl::meta::Type<getBarFactoryComponent()::<lambda(std::unique_ptr<Qux, std::default_delete<Qux> >)> > >::type>::type, fruit::impl::meta::ProcessDeferredBindings>::type; F2 = fruit::impl::meta::ComponentFunctor::apply<fruit::impl::meta::ConvertComponent, fruit::impl::meta::Comp<fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<fruit::impl::meta::Type<std::function<std::unique_ptr<Bar, std::default_delete<Bar> >(std::unique_ptr<Qux, std::default_delete<Qux> >)> > >, fruit::impl::meta::Vector<fruit::impl::meta::Type<std::function<std::unique_ptr<Bar, std::default_delete<Bar> >(std::unique_ptr<Qux, std::default_delete<Qux> >)> > >, fruit::impl::meta::Vector<fruit::impl::meta::Pair<fruit::impl::meta::Type<std::function<std::unique_ptr<Bar, std::default_delete<Bar> >(std::unique_ptr<Qux, std::default_delete<Qux> >)> >, fruit::impl::meta::Vector<> > >, fruit::impl::meta::Vector<>, fruit::impl::meta::EmptyList> >::type]’
/home/me/.conan/data/fruit/3.6.0/_/_/package/99fe6edc64c98b6ead2c33cb2b0bf89b59d7f7ce/include/fruit/impl/component.defn.h:66:7:   required from ‘fruit::Component<Types>::Component(fruit::PartialComponent<Bindings ...>&&) [with Bindings = {fruit::impl::RegisterFactory<std::unique_ptr<BarImpl, std::default_delete<BarImpl> >(fruit::Assisted<std::unique_ptr<Qux, std::default_delete<Qux> > >), getBarFactoryComponent()::<lambda(std::unique_ptr<Qux, std::default_delete<Qux> >)> >, fruit::impl::Bind<Bar, BarImpl>}; Params = {std::function<std::unique_ptr<Bar, std::default_delete<Bar> >(std::unique_ptr<Qux, std::default_delete<Qux> >)>}]’
main.cpp:53:18:   required from here
/home/me/.conan/data/fruit/3.6.0/_/_/package/99fe6edc64c98b6ead2c33cb2b0bf89b59d7f7ce/include/fruit/impl/component_functors.defn.h:919:28: error: use of deleted function ‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = Qux; _Dp = std::default_delete<Qux>]’
  919 |             NakedC* c = fun(args...).release();
      |                         ~~~^~~~~~~~~
In file included from /usr/include/c++/9/memory:80,
                 from main.cpp:3:
/usr/include/c++/9/bits/unique_ptr.h:414:7: note: declared here
  414 |       unique_ptr(const unique_ptr&) = delete;
      |       ^~~~~~~~~~
In file included from /usr/include/c++/9/functional:59,
                 from main.cpp:2:
/usr/include/c++/9/bits/std_function.h:684:25: note:   initializing argument 1 of ‘_Res std::function<_Res(_ArgTypes ...)>::operator()(_ArgTypes ...) const [with _Res = std::unique_ptr<BarImpl>; _ArgTypes = {std::unique_ptr<Qux, std::default_delete<Qux> >}]’
  684 |     operator()(_ArgTypes... __args) const
      |                ~~~~~~~~~^~~~~~~~~~
In file included from /home/me/.conan/data/fruit/3.6.0/_/_/package/99fe6edc64c98b6ead2c33cb2b0bf89b59d7f7ce/include/fruit/component.h:25,
                 from /home/me/.conan/data/fruit/3.6.0/_/_/package/99fe6edc64c98b6ead2c33cb2b0bf89b59d7f7ce/include/fruit/fruit.h:27,
                 from main.cpp:5:
/home/me/.conan/data/fruit/3.6.0/_/_/package/99fe6edc64c98b6ead2c33cb2b0bf89b59d7f7ce/include/fruit/impl/component_functors.defn.h: In instantiation of ‘Arg fruit::impl::meta::GetAssistedArg<numAssistedBefore, numNonAssistedBefore, fruit::Assisted<Arg> >::operator()(InjectedArgsTuple&, UserProvidedArgsTuple&) [with InjectedArgsTuple = std::tuple<>; UserProvidedArgsTuple = std::tuple<std::unique_ptr<Qux, std::default_delete<Qux> >&>; int numAssistedBefore = 0; int numNonAssistedBefore = 0; Arg = std::unique_ptr<Qux>]’:
/home/me/.conan/data/fruit/3.6.0/_/_/package/99fe6edc64c98b6ead2c33cb2b0bf89b59d7f7ce/include/fruit/impl/component_functors.defn.h:452:95:   required from ‘void fruit::impl::meta::RegisterFactoryHelper::apply<Comp, DecoratedSignature, Lambda, fruit::impl::meta::Type<NakedC(NakedUserProvidedArgs ...)>, fruit::impl::meta::Type<NakedC(NakedAllArgs ...)>, fruit::impl::meta::Vector<InjectedAnnotatedArgs ...>, fruit::impl::meta::Vector<fruit::impl::meta::Type<NakedInjectedArgs>...>, fruit::impl::meta::Vector<Indexes ...> >::Op::operator()(fruit::impl::FixedSizeVector<fruit::impl::ComponentStorageEntry>&) [with Comp = fruit::impl::meta::Comp<fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<fruit::impl::meta::Pair<fruit::impl::meta::Type<Bar>, fruit::impl::meta::Type<BarImpl> > >, fruit::impl::meta::EmptyList>; DecoratedSignature = fruit::impl::meta::Type<std::unique_ptr<BarImpl>(fruit::Assisted<std::unique_ptr<Qux> >)>; Lambda = fruit::impl::meta::Type<getBarFactoryComponent()::<lambda(std::unique_ptr<Qux>)> >; NakedC = std::unique_ptr<BarImpl>; NakedUserProvidedArgs = {std::unique_ptr<Qux, std::default_delete<Qux> >}; NakedAllArgs = {std::unique_ptr<Qux, std::default_delete<Qux> >}; InjectedAnnotatedArgs = {}; NakedInjectedArgs = {}; Indexes = {fruit::impl::meta::Int<0>}]’
/home/me/.conan/data/fruit/3.6.0/_/_/package/99fe6edc64c98b6ead2c33cb2b0bf89b59d7f7ce/include/fruit/impl/component_functors.defn.h:88:24:   recursively required from ‘void fruit::impl::meta::Compose2ComponentFunctors::apply<F1, F2>::type::apply<Comp>::Op::operator()(fruit::impl::FixedSizeVector<fruit::impl::ComponentStorageEntry>&) [with Comp = fruit::impl::meta::Comp<fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<>, fruit::impl::meta::EmptyList>; F1 = fruit::impl::meta::Compose2ComponentFunctors::apply<fruit::impl::meta::ComponentFunctor::apply<fruit::impl::meta::AddDeferredInterfaceBinding, fruit::impl::meta::Type<Bar>, fruit::impl::meta::Type<BarImpl> >::type, fruit::impl::meta::ComponentFunctor::apply<fruit::impl::meta::RegisterFactory, fruit::impl::meta::Type<std::unique_ptr<BarImpl, std::default_delete<BarImpl> >(fruit::Assisted<std::unique_ptr<Qux, std::default_delete<Qux> > >)>, fruit::impl::meta::Type<getBarFactoryComponent()::<lambda(std::unique_ptr<Qux, std::default_delete<Qux> >)> > >::type>::type; F2 = fruit::impl::meta::ProcessDeferredBindings]’
/home/me/.conan/data/fruit/3.6.0/_/_/package/99fe6edc64c98b6ead2c33cb2b0bf89b59d7f7ce/include/fruit/impl/component_functors.defn.h:88:24:   required from ‘void fruit::impl::meta::Compose2ComponentFunctors::apply<F1, F2>::type::apply<Comp>::Op::operator()(fruit::impl::FixedSizeVector<fruit::impl::ComponentStorageEntry>&) [with Comp = fruit::impl::meta::Comp<fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<>, fruit::impl::meta::EmptyList>; F1 = fruit::impl::meta::Compose2ComponentFunctors::apply<fruit::impl::meta::Compose2ComponentFunctors::apply<fruit::impl::meta::ComponentFunctor::apply<fruit::impl::meta::AddDeferredInterfaceBinding, fruit::impl::meta::Type<Bar>, fruit::impl::meta::Type<BarImpl> >::type, fruit::impl::meta::ComponentFunctor::apply<fruit::impl::meta::RegisterFactory, fruit::impl::meta::Type<std::unique_ptr<BarImpl, std::default_delete<BarImpl> >(fruit::Assisted<std::unique_ptr<Qux, std::default_delete<Qux> > >)>, fruit::impl::meta::Type<getBarFactoryComponent()::<lambda(std::unique_ptr<Qux, std::default_delete<Qux> >)> > >::type>::type, fruit::impl::meta::ProcessDeferredBindings>::type; F2 = fruit::impl::meta::ComponentFunctor::apply<fruit::impl::meta::ConvertComponent, fruit::impl::meta::Comp<fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<fruit::impl::meta::Type<std::function<std::unique_ptr<Bar, std::default_delete<Bar> >(std::unique_ptr<Qux, std::default_delete<Qux> >)> > >, fruit::impl::meta::Vector<fruit::impl::meta::Type<std::function<std::unique_ptr<Bar, std::default_delete<Bar> >(std::unique_ptr<Qux, std::default_delete<Qux> >)> > >, fruit::impl::meta::Vector<fruit::impl::meta::Pair<fruit::impl::meta::Type<std::function<std::unique_ptr<Bar, std::default_delete<Bar> >(std::unique_ptr<Qux, std::default_delete<Qux> >)> >, fruit::impl::meta::Vector<> > >, fruit::impl::meta::Vector<>, fruit::impl::meta::EmptyList> >::type]’
/home/me/.conan/data/fruit/3.6.0/_/_/package/99fe6edc64c98b6ead2c33cb2b0bf89b59d7f7ce/include/fruit/impl/component.defn.h:66:7:   required from ‘fruit::Component<Types>::Component(fruit::PartialComponent<Bindings ...>&&) [with Bindings = {fruit::impl::RegisterFactory<std::unique_ptr<BarImpl, std::default_delete<BarImpl> >(fruit::Assisted<std::unique_ptr<Qux, std::default_delete<Qux> > >), getBarFactoryComponent()::<lambda(std::unique_ptr<Qux, std::default_delete<Qux> >)> >, fruit::impl::Bind<Bar, BarImpl>}; Params = {std::function<std::unique_ptr<Bar, std::default_delete<Bar> >(std::unique_ptr<Qux, std::default_delete<Qux> >)>}]’
main.cpp:53:18:   required from here
/home/me/.conan/data/fruit/3.6.0/_/_/package/99fe6edc64c98b6ead2c33cb2b0bf89b59d7f7ce/include/fruit/impl/component_functors.defn.h:405:58: error: use of deleted function ‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = Qux; _Dp = std::default_delete<Qux>]’
  405 |     return std::get<numAssistedBefore>(user_provided_args);
      |                                                          ^
In file included from /usr/include/c++/9/memory:80,
                 from main.cpp:3:
/usr/include/c++/9/bits/unique_ptr.h:414:7: note: declared here
  414 |       unique_ptr(const unique_ptr&) = delete;
      |       ^~~~~~~~~~
In file included from /usr/include/c++/9/functional:59,
                 from main.cpp:2:
/usr/include/c++/9/bits/std_function.h:667:7: error: ‘std::function<_Res(_ArgTypes ...)>::function(_Functor) [with _Functor = fruit::impl::meta::AutoRegisterFactoryHelper::apply<Comp, TargetRequirements, TargetNonConstRequirements, AnnotatedC, unused1, unused2, fruit::impl::meta::Type<std::unique_ptr<NakedI> >, AnnotatedSignature, Args ...>::Op::operator()(fruit::impl::FixedSizeVector<fruit::impl::ComponentStorageEntry>&) [with Comp = fruit::impl::meta::Comp<fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<fruit::impl::meta::Type<std::function<std::unique_ptr<BarImpl, std::default_delete<BarImpl> >(std::unique_ptr<Qux, std::default_delete<Qux> >)> > >, fruit::impl::meta::Vector<fruit::impl::meta::Type<std::function<std::unique_ptr<BarImpl, std::default_delete<BarImpl> >(std::unique_ptr<Qux, std::default_delete<Qux> >)> > >, fruit::impl::meta::Vector<fruit::impl::meta::Pair<fruit::impl::meta::Type<std::function<std::unique_ptr<BarImpl, std::default_delete<BarImpl> >(std::unique_ptr<Qux, std::default_delete<Qux> >)> >, fruit::impl::meta::Vector<> > >, fruit::impl::meta::Vector<fruit::impl::meta::Pair<fruit::impl::meta::Type<Bar>, fruit::impl::meta::Type<BarImpl> > >, fruit::impl::meta::EmptyList>; TargetRequirements = fruit::impl::meta::Vector<>; TargetNonConstRequirements = fruit::impl::meta::Vector<>; AnnotatedC = fruit::impl::meta::Type<BarImpl>; unused1 = fruit::impl::meta::Bool<false>; unused2 = fruit::impl::meta::Bool<true>; NakedI = Bar; AnnotatedSignature = fruit::impl::meta::Type<std::unique_ptr<Bar>(std::unique_ptr<Qux>)>; Args = {fruit::impl::meta::Type<std::unique_ptr<Qux, std::default_delete<Qux> > >}]::<lambda(fruit::impl::meta::UnwrapType<fruit::impl::meta::Type<std::function<std::unique_ptr<BarImpl>(std::unique_ptr<Qux>)> > >&)>::<lambda(fruit::impl::meta::Type<std::unique_ptr<Qux> >::type)>; <template-parameter-2-2> = void; <template-parameter-2-3> = void; _Res = std::unique_ptr<Bar>; _ArgTypes = {std::unique_ptr<Qux, std::default_delete<Qux> >}]’, declared using local type ‘fruit::impl::meta::AutoRegisterFactoryHelper::apply<Comp, TargetRequirements, TargetNonConstRequirements, AnnotatedC, unused1, unused2, fruit::impl::meta::Type<std::unique_ptr<NakedI> >, AnnotatedSignature, Args ...>::Op::operator()(fruit::impl::FixedSizeVector<fruit::impl::ComponentStorageEntry>&) [with Comp = fruit::impl::meta::Comp<fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<fruit::impl::meta::Type<std::function<std::unique_ptr<BarImpl, std::default_delete<BarImpl> >(std::unique_ptr<Qux, std::default_delete<Qux> >)> > >, fruit::impl::meta::Vector<fruit::impl::meta::Type<std::function<std::unique_ptr<BarImpl, std::default_delete<BarImpl> >(std::unique_ptr<Qux, std::default_delete<Qux> >)> > >, fruit::impl::meta::Vector<fruit::impl::meta::Pair<fruit::impl::meta::Type<std::function<std::unique_ptr<BarImpl, std::default_delete<BarImpl> >(std::unique_ptr<Qux, std::default_delete<Qux> >)> >, fruit::impl::meta::Vector<> > >, fruit::impl::meta::Vector<fruit::impl::meta::Pair<fruit::impl::meta::Type<Bar>, fruit::impl::meta::Type<BarImpl> > >, fruit::impl::meta::EmptyList>; TargetRequirements = fruit::impl::meta::Vector<>; TargetNonConstRequirements = fruit::impl::meta::Vector<>; AnnotatedC = fruit::impl::meta::Type<BarImpl>; unused1 = fruit::impl::meta::Bool<false>; unused2 = fruit::impl::meta::Bool<true>; NakedI = Bar; AnnotatedSignature = fruit::impl::meta::Type<std::unique_ptr<Bar>(std::unique_ptr<Qux>)>; Args = {fruit::impl::meta::Type<std::unique_ptr<Qux, std::default_delete<Qux> > >}]::<lambda(fruit::impl::meta::UnwrapType<fruit::impl::meta::Type<std::function<std::unique_ptr<BarImpl>(std::unique_ptr<Qux>)> > >&)>::<lambda(fruit::impl::meta::Type<std::unique_ptr<Qux> >::type)>’, is used but never defined [-fpermissive]
  667 |       function<_Res(_ArgTypes...)>::
      |       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~

Also, I am confused about the need for the bind() call now that Bar is not specified anywhere in the factory component function. I tried removing it, but I ended up getting errors like

error: static assertion failed: No explicit binding was found for T, and note that C is an abstract class (so Fruit can't auto-inject this type, even if it has an Inject typedef or an INJECT annotation that will be ignored).

From the error messages, it seems like the bind() is required so I put it back in. But I don't understand the need for it.

@tt4g
Copy link
Contributor

tt4g commented Sep 20, 2020

It seems that std::unique_ptr cannot be used as the Functor's argument to register the fruit::registerFactory.
Replace std::unique_ptr<Qux> with std::shared_ptr<Qux>.

The following code works in my hands:
#include <fruit/fruit.h>

#include <iostream>
#include <functional>
#include <memory>
#include <utility>

class Qux {
public:
    void test() {
        std::cout << "Qux" << std::endl;
    }
};

class Bar {
public:
    virtual ~Bar() {}
    virtual void test() = 0;
};

class BarImpl : public Bar {

    std::shared_ptr<Qux> ptr_;

public:

    explicit BarImpl(std::shared_ptr<Qux> ptr)
        : ptr_(std::move(ptr))
    {

    }

    void test() override {
        std::cout << "BarImpl" << std::endl;
        ptr_->test();
    }
};

using BarFactory = std::function<std::unique_ptr<Bar>(std::shared_ptr<Qux>)>;

fruit::Component<BarFactory> getBarFactoryComponent() {
    return fruit::createComponent()
        .bind<Bar, BarImpl>()
        .registerFactory<std::unique_ptr<BarImpl>(fruit::Assisted<std::shared_ptr<Qux>>)>(
                [](std::shared_ptr<Qux> ptr) {
                    return std::make_unique<BarImpl>(std::move(ptr));
                });
}

class Foo {
public:
    virtual void test() = 0;
    virtual ~Foo() {}
};

class FooImpl : public Foo {
    BarFactory& factory_;
public:
    INJECT(FooImpl(BarFactory& factory)) : factory_(factory) {}

    void test() override {
        std::cout << "FooImpl" << std::endl;
        auto bar_ptr = factory_(std::make_unique<Qux>());
        bar_ptr->test();
    }
};

fruit::Component<Foo> getFooComponent() {
    return fruit::createComponent()
        .install(getBarFactoryComponent)
        .bind<Foo, FooImpl>();
}

int main(int argc, char** argv) {
    fruit::Injector<Foo> injector(getFooComponent);
    Foo& instance = injector.get<Foo&>();

    instance.test();
    return 0;
}

@tt4g
Copy link
Contributor

tt4g commented Sep 20, 2020

From the error messages, it seems like the bind() is required so I put it back in. But I don't understand the need for it.

The fruit needs to be internally bound to a pure virtual class and its implementation.
For the types to be injected, it is important to know the types to be injected as implementations.

Without the type information, when BarImpl inherits Foo and Bar, if multiple BarImpl are registered in fruit, fruit can't tell whether BarImpl is injected into Foo, Bar, or both.

Wiki has more details: https://github.com/google/fruit/wiki/tutorial:-getting-started

@dfontenot
Copy link
Author

@tt4g thanks for looking into this issue. I believe in this scenario I can use a shared_ptr, although a unique_ptr would make more sense. This issue can be closed.

@tt4g
Copy link
Contributor

tt4g commented Sep 20, 2020

The use of std::unique_ptr would be better for many use cases.
I don't see where the reason for that is not possible.

@dfontenot
Copy link
Author

Perhaps this could be a feature request?

@poletti-marco
Copy link
Contributor

I agree this should be supported. Just committed 9284588 that should fix this issue.
Could you please try again with Fruit master and check if it works now as you expect?
If it works then I can cut a bugfix release.

@tt4g : as always thanks a lot for helping out here!

@dfontenot
Copy link
Author

@poletti-marco @tt4g will try using the latest master soon and will let you know. Thanks again for looking into this so quickly!

@dfontenot
Copy link
Author

@poletti-marco I'm still running into compilation issues on Fruit master. Here is the error.

In file included from /home/me/workspace/test2/fruit/include/fruit/component.h:25,
                 from /home/me/workspace/test2/fruit/include/fruit/fruit.h:27,
                 from main.cpp:5:
/home/me/workspace/test2/fruit/include/fruit/impl/component_functors.defn.h: In instantiation of ‘void fruit::impl::meta::AutoRegisterFactoryHelper::apply<Comp, TargetRequirements, TargetNonConstRequirements, AnnotatedC, unused1, unused2, fruit::impl::meta::Type<std::unique_ptr<NakedI> >, AnnotatedSignature, Args ...>::Op::operator()(fruit::impl::FixedSizeVector<fruit::impl::ComponentStorageEntry>&) [with Comp = fruit::impl::meta::Comp<fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<fruit::impl::meta::Type<std::function<std::unique_ptr<BarImpl, std::default_delete<BarImpl> >(std::unique_ptr<Qux, std::default_delete<Qux> >)> > >, fruit::impl::meta::Vector<fruit::impl::meta::Type<std::function<std::unique_ptr<BarImpl, std::default_delete<BarImpl> >(std::unique_ptr<Qux, std::default_delete<Qux> >)> > >, fruit::impl::meta::Vector<fruit::impl::meta::Pair<fruit::impl::meta::Type<std::function<std::unique_ptr<BarImpl, std::default_delete<BarImpl> >(std::unique_ptr<Qux, std::default_delete<Qux> >)> >, fruit::impl::meta::Vector<> > >, fruit::impl::meta::Vector<fruit::impl::meta::Pair<fruit::impl::meta::Type<Bar>, fruit::impl::meta::Type<BarImpl> > >, fruit::impl::meta::EmptyList>; TargetRequirements = fruit::impl::meta::Vector<>; TargetNonConstRequirements = fruit::impl::meta::Vector<>; AnnotatedC = fruit::impl::meta::Type<BarImpl>; unused1 = fruit::impl::meta::Bool<false>; unused2 = fruit::impl::meta::Bool<true>; NakedI = Bar; AnnotatedSignature = fruit::impl::meta::Type<std::unique_ptr<Bar>(std::unique_ptr<Qux>)>; Args = {fruit::impl::meta::Type<std::unique_ptr<Qux, std::default_delete<Qux> > >}]’:
/home/me/workspace/test2/fruit/include/fruit/impl/component_functors.defn.h:88:24:   required from ‘void fruit::impl::meta::Compose2ComponentFunctors::apply<F1, F2>::type::apply<Comp>::Op::operator()(fruit::impl::FixedSizeVector<fruit::impl::ComponentStorageEntry>&) [with Comp = fruit::impl::meta::Comp<fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<fruit::impl::meta::Type<std::function<std::unique_ptr<BarImpl, std::default_delete<BarImpl> >(std::unique_ptr<Qux, std::default_delete<Qux> >)> > >, fruit::impl::meta::Vector<fruit::impl::meta::Type<std::function<std::unique_ptr<BarImpl, std::default_delete<BarImpl> >(std::unique_ptr<Qux, std::default_delete<Qux> >)> > >, fruit::impl::meta::Vector<fruit::impl::meta::Pair<fruit::impl::meta::Type<std::function<std::unique_ptr<BarImpl, std::default_delete<BarImpl> >(std::unique_ptr<Qux, std::default_delete<Qux> >)> >, fruit::impl::meta::Vector<> > >, fruit::impl::meta::Vector<fruit::impl::meta::Pair<fruit::impl::meta::Type<Bar>, fruit::impl::meta::Type<BarImpl> > >, fruit::impl::meta::EmptyList>; F1 = fruit::impl::meta::ComponentFunctor::apply<fruit::impl::meta::EnsureProvidedType, fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<>, fruit::impl::meta::Type<std::function<std::unique_ptr<Bar, std::default_delete<Bar> >(std::unique_ptr<Qux, std::default_delete<Qux> >)> >, fruit::impl::meta::Bool<true> >::type; F2 = fruit::impl::meta::ComponentFunctorIdentity]’
/home/me/workspace/test2/fruit/include/fruit/impl/component_functors.defn.h:87:24:   required from ‘void fruit::impl::meta::Compose2ComponentFunctors::apply<F1, F2>::type::apply<Comp>::Op::operator()(fruit::impl::FixedSizeVector<fruit::impl::ComponentStorageEntry>&) [with Comp = fruit::impl::meta::Comp<fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<>, fruit::impl::meta::EmptyList>; F1 = fruit::impl::meta::Compose2ComponentFunctors::apply<fruit::impl::meta::Compose2ComponentFunctors::apply<fruit::impl::meta::ComponentFunctor::apply<fruit::impl::meta::AddDeferredInterfaceBinding, fruit::impl::meta::Type<Bar>, fruit::impl::meta::Type<BarImpl> >::type, fruit::impl::meta::ComponentFunctor::apply<fruit::impl::meta::RegisterFactory, fruit::impl::meta::Type<std::unique_ptr<BarImpl, std::default_delete<BarImpl> >(fruit::Assisted<std::unique_ptr<Qux, std::default_delete<Qux> > >)>, fruit::impl::meta::Type<getBarFactoryComponent()::<lambda(std::unique_ptr<Qux, std::default_delete<Qux> >)> > >::type>::type, fruit::impl::meta::ProcessDeferredBindings>::type; F2 = fruit::impl::meta::ComponentFunctor::apply<fruit::impl::meta::ConvertComponent, fruit::impl::meta::Comp<fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<fruit::impl::meta::Type<std::function<std::unique_ptr<Bar, std::default_delete<Bar> >(std::unique_ptr<Qux, std::default_delete<Qux> >)> > >, fruit::impl::meta::Vector<fruit::impl::meta::Type<std::function<std::unique_ptr<Bar, std::default_delete<Bar> >(std::unique_ptr<Qux, std::default_delete<Qux> >)> > >, fruit::impl::meta::Vector<fruit::impl::meta::Pair<fruit::impl::meta::Type<std::function<std::unique_ptr<Bar, std::default_delete<Bar> >(std::unique_ptr<Qux, std::default_delete<Qux> >)> >, fruit::impl::meta::Vector<> > >, fruit::impl::meta::Vector<>, fruit::impl::meta::EmptyList> >::type]’
/home/me/workspace/test2/fruit/include/fruit/impl/component.defn.h:66:7:   required from ‘fruit::Component<Types>::Component(fruit::PartialComponent<Bindings ...>&&) [with Bindings = {fruit::impl::RegisterFactory<std::unique_ptr<BarImpl, std::default_delete<BarImpl> >(fruit::Assisted<std::unique_ptr<Qux, std::default_delete<Qux> > >), getBarFactoryComponent()::<lambda(std::unique_ptr<Qux, std::default_delete<Qux> >)> >, fruit::impl::Bind<Bar, BarImpl>}; Params = {std::function<std::unique_ptr<Bar, std::default_delete<Bar> >(std::unique_ptr<Qux, std::default_delete<Qux> >)>}]’
main.cpp:53:18:   required from here
/home/me/workspace/test2/fruit/include/fruit/impl/component_functors.defn.h:919:28: error: use of deleted function ‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = Qux; _Dp = std::default_delete<Qux>]’
  919 |             NakedC* c = fun(args...).release();
      |                         ~~~^~~~~~~~~
In file included from /usr/include/c++/9/memory:80,
                 from main.cpp:3:
/usr/include/c++/9/bits/unique_ptr.h:414:7: note: declared here
  414 |       unique_ptr(const unique_ptr&) = delete;
      |       ^~~~~~~~~~
In file included from /usr/include/c++/9/functional:59,
                 from main.cpp:2:
/usr/include/c++/9/bits/std_function.h:684:25: note:   initializing argument 1 of ‘_Res std::function<_Res(_ArgTypes ...)>::operator()(_ArgTypes ...) const [with _Res = std::unique_ptr<BarImpl>; _ArgTypes = {std::unique_ptr<Qux, std::default_delete<Qux> >}]’
  684 |     operator()(_ArgTypes... __args) const
      |                ~~~~~~~~~^~~~~~~~~~
/usr/include/c++/9/bits/std_function.h:667:7: error: ‘std::function<_Res(_ArgTypes ...)>::function(_Functor) [with _Functor = fruit::impl::meta::AutoRegisterFactoryHelper::apply<Comp, TargetRequirements, TargetNonConstRequirements, AnnotatedC, unused1, unused2, fruit::impl::meta::Type<std::unique_ptr<NakedI> >, AnnotatedSignature, Args ...>::Op::operator()(fruit::impl::FixedSizeVector<fruit::impl::ComponentStorageEntry>&) [with Comp = fruit::impl::meta::Comp<fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<fruit::impl::meta::Type<std::function<std::unique_ptr<BarImpl, std::default_delete<BarImpl> >(std::unique_ptr<Qux, std::default_delete<Qux> >)> > >, fruit::impl::meta::Vector<fruit::impl::meta::Type<std::function<std::unique_ptr<BarImpl, std::default_delete<BarImpl> >(std::unique_ptr<Qux, std::default_delete<Qux> >)> > >, fruit::impl::meta::Vector<fruit::impl::meta::Pair<fruit::impl::meta::Type<std::function<std::unique_ptr<BarImpl, std::default_delete<BarImpl> >(std::unique_ptr<Qux, std::default_delete<Qux> >)> >, fruit::impl::meta::Vector<> > >, fruit::impl::meta::Vector<fruit::impl::meta::Pair<fruit::impl::meta::Type<Bar>, fruit::impl::meta::Type<BarImpl> > >, fruit::impl::meta::EmptyList>; TargetRequirements = fruit::impl::meta::Vector<>; TargetNonConstRequirements = fruit::impl::meta::Vector<>; AnnotatedC = fruit::impl::meta::Type<BarImpl>; unused1 = fruit::impl::meta::Bool<false>; unused2 = fruit::impl::meta::Bool<true>; NakedI = Bar; AnnotatedSignature = fruit::impl::meta::Type<std::unique_ptr<Bar>(std::unique_ptr<Qux>)>; Args = {fruit::impl::meta::Type<std::unique_ptr<Qux, std::default_delete<Qux> > >}]::<lambda(fruit::impl::meta::UnwrapType<fruit::impl::meta::Type<std::function<std::unique_ptr<BarImpl>(std::unique_ptr<Qux>)> > >&)>::<lambda(fruit::impl::meta::Type<std::unique_ptr<Qux> >::type)>; <template-parameter-2-2> = void; <template-parameter-2-3> = void; _Res = std::unique_ptr<Bar>; _ArgTypes = {std::unique_ptr<Qux, std::default_delete<Qux> >}]’, declared using local type ‘fruit::impl::meta::AutoRegisterFactoryHelper::apply<Comp, TargetRequirements, TargetNonConstRequirements, AnnotatedC, unused1, unused2, fruit::impl::meta::Type<std::unique_ptr<NakedI> >, AnnotatedSignature, Args ...>::Op::operator()(fruit::impl::FixedSizeVector<fruit::impl::ComponentStorageEntry>&) [with Comp = fruit::impl::meta::Comp<fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<fruit::impl::meta::Type<std::function<std::unique_ptr<BarImpl, std::default_delete<BarImpl> >(std::unique_ptr<Qux, std::default_delete<Qux> >)> > >, fruit::impl::meta::Vector<fruit::impl::meta::Type<std::function<std::unique_ptr<BarImpl, std::default_delete<BarImpl> >(std::unique_ptr<Qux, std::default_delete<Qux> >)> > >, fruit::impl::meta::Vector<fruit::impl::meta::Pair<fruit::impl::meta::Type<std::function<std::unique_ptr<BarImpl, std::default_delete<BarImpl> >(std::unique_ptr<Qux, std::default_delete<Qux> >)> >, fruit::impl::meta::Vector<> > >, fruit::impl::meta::Vector<fruit::impl::meta::Pair<fruit::impl::meta::Type<Bar>, fruit::impl::meta::Type<BarImpl> > >, fruit::impl::meta::EmptyList>; TargetRequirements = fruit::impl::meta::Vector<>; TargetNonConstRequirements = fruit::impl::meta::Vector<>; AnnotatedC = fruit::impl::meta::Type<BarImpl>; unused1 = fruit::impl::meta::Bool<false>; unused2 = fruit::impl::meta::Bool<true>; NakedI = Bar; AnnotatedSignature = fruit::impl::meta::Type<std::unique_ptr<Bar>(std::unique_ptr<Qux>)>; Args = {fruit::impl::meta::Type<std::unique_ptr<Qux, std::default_delete<Qux> > >}]::<lambda(fruit::impl::meta::UnwrapType<fruit::impl::meta::Type<std::function<std::unique_ptr<BarImpl>(std::unique_ptr<Qux>)> > >&)>::<lambda(fruit::impl::meta::Type<std::unique_ptr<Qux> >::type)>’, is used but never defined [-fpermissive]
  667 |       function<_Res(_ArgTypes...)>::
      |       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~

@tt4g
Copy link
Contributor

tt4g commented Sep 23, 2020

@dfontenot Can you try to replace std::unique_ptr<Qux> with std::unique_ptr<Qux>& in the factory function and then compile it?

Component<BarFactory> getBarFactoryComponent() {
    return createComponent()
        .bind<Bar, BarImpl>()
-        .registerFactory<unique_ptr<BarImpl>(Assisted<unique_ptr<Qux>>)>(
-                [](unique_ptr<Qux> ptr) {
+        .registerFactory<unique_ptr<BarImpl>(Assisted<unique_ptr<Qux>&>)>(
+                [](unique_ptr<Qux> &ptr) {
                    return std::make_unique<BarImpl>(move(ptr));
                });
}

@dfontenot
Copy link
Author

@tt4g I applied the change, and I also updated the type definition of bar factory. From there, I had to update the use of BarFactory to receive an lvalue instead of an rvalue. I'm running into a different Fruit error. I'm going to post the code as I have it now along with the error message.

#include <iostream>
#include <functional>
#include <memory>
#include <utility>
#include "fruit/fruit.h"

using namespace fruit;
using namespace std;

class Qux {
public:
    void test() {
        cout << "Qux" << endl;
    }
};

class Bar {
public:
    virtual ~Bar() {}
    virtual void test() = 0;
};

class BarImpl : public Bar {
    unique_ptr<Qux> ptr_;
public:
    //BarImpl(unique_ptr<Qux>&& ptr) : ptr_(move(ptr)) {}
    BarImpl(unique_ptr<Qux> ptr) : ptr_(move(ptr)) {}
    BarImpl(BarImpl&& b) : ptr_(move(b.ptr_)) {}

    void test() override {
        cout << "BarImpl" << endl;
        ptr_->test();
    }
};

using BarFactory = function<unique_ptr<Bar>(unique_ptr<Qux>&)>;

Component<BarFactory> getBarFactoryComponent() {
    return createComponent()
        .bind<Bar, BarImpl>()
        .registerFactory<unique_ptr<BarImpl>(Assisted<unique_ptr<Qux>& >)>(
                [](unique_ptr<Qux>& ptr) {
                    //return unique_ptr<Bar>(move(new BarImpl(move(ptr))));

                    //BarImpl* b = new BarImpl(move(ptr));
                    //Bar* b = new BarImpl(move(ptr));
                    //return make_unique<Bar>(move(b));
                    return make_unique<BarImpl>(move(ptr));
                   // return unique_ptr<Bar>(move(b));

                    //return unique_ptr<Bar>(move(new BarImpl(move(ptr))));
                    //return make_unique<BarImpl>(move(ptr));
                });
}

class Foo {
public:
    virtual void test() = 0;
    virtual ~Foo() {}
};

class FooImpl : public Foo {
    BarFactory& factory_;
public:
    INJECT(FooImpl(BarFactory& factory)) : factory_(factory) {}

    void test() override {
        cout << "FooImpl" << endl;
        auto qux = make_unique<Qux>();
        auto bar_ptr = factory_(qux);
        bar_ptr->test();
    }
};

Component<Foo> getFooComponent() {
    return createComponent().install(getBarFactoryComponent).bind<Foo, FooImpl>();
}

int main(int argc, char** argv) {
    Injector<Foo> injector(getFooComponent);
    Foo& instance = injector.get<Foo&>();

    instance.test();
    return 0;
}

Here is the new error

In file included from /home/me/workspace/test2/fruit/include/fruit/component.h:25,
                 from /home/me/workspace/test2/fruit/include/fruit/fruit.h:27,
                 from main.cpp:5:
/home/me/workspace/test2/fruit/include/fruit/impl/component_functors.defn.h: In instantiation of ‘void fruit::impl::meta::RegisterFactoryHelper::apply<Comp, DecoratedSignature, Lambda, fruit::impl::meta::Type<NakedC(NakedUserProvidedArgs ...)>, fruit::impl::meta::Type<NakedC(NakedAllArgs ...)>, fruit::impl::meta::Vector<InjectedAnnotatedArgs ...>, fruit::impl::meta::Vector<fruit::impl::meta::Type<NakedInjectedArgs>...>, fruit::impl::meta::Vector<Indexes ...> >::Op::operator()(fruit::impl::FixedSizeVector<fruit::impl::ComponentStorageEntry>&) [with Comp = fruit::impl::meta::Comp<fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<fruit::impl::meta::Pair<fruit::impl::meta::Type<Bar>, fruit::impl::meta::Type<BarImpl> > >, fruit::impl::meta::EmptyList>; DecoratedSignature = fruit::impl::meta::Type<std::unique_ptr<BarImpl>(fruit::Assisted<std::unique_ptr<Qux>&>)>; Lambda = fruit::impl::meta::Type<getBarFactoryComponent()::<lambda(std::unique_ptr<Qux>&)> >; NakedC = std::unique_ptr<BarImpl>; NakedUserProvidedArgs = {std::unique_ptr<Qux, std::default_delete<Qux> >&}; NakedAllArgs = {std::unique_ptr<Qux, std::default_delete<Qux> >&}; InjectedAnnotatedArgs = {}; NakedInjectedArgs = {}; Indexes = {fruit::impl::meta::Int<0>}]’:
/home/me/workspace/test2/fruit/include/fruit/impl/component_functors.defn.h:88:24:   recursively required from ‘void fruit::impl::meta::Compose2ComponentFunctors::apply<F1, F2>::type::apply<Comp>::Op::operator()(fruit::impl::FixedSizeVector<fruit::impl::ComponentStorageEntry>&) [with Comp = fruit::impl::meta::Comp<fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<>, fruit::impl::meta::EmptyList>; F1 = fruit::impl::meta::Compose2ComponentFunctors::apply<fruit::impl::meta::ComponentFunctor::apply<fruit::impl::meta::AddDeferredInterfaceBinding, fruit::impl::meta::Type<Bar>, fruit::impl::meta::Type<BarImpl> >::type, fruit::impl::meta::ComponentFunctor::apply<fruit::impl::meta::RegisterFactory, fruit::impl::meta::Type<std::unique_ptr<BarImpl, std::default_delete<BarImpl> >(fruit::Assisted<std::unique_ptr<Qux, std::default_delete<Qux> >&>)>, fruit::impl::meta::Type<getBarFactoryComponent()::<lambda(std::unique_ptr<Qux, std::default_delete<Qux> >&)> > >::type>::type; F2 = fruit::impl::meta::ProcessDeferredBindings]’
/home/me/workspace/test2/fruit/include/fruit/impl/component_functors.defn.h:88:24:   required from ‘void fruit::impl::meta::Compose2ComponentFunctors::apply<F1, F2>::type::apply<Comp>::Op::operator()(fruit::impl::FixedSizeVector<fruit::impl::ComponentStorageEntry>&) [with Comp = fruit::impl::meta::Comp<fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<>, fruit::impl::meta::EmptyList>; F1 = fruit::impl::meta::Compose2ComponentFunctors::apply<fruit::impl::meta::Compose2ComponentFunctors::apply<fruit::impl::meta::ComponentFunctor::apply<fruit::impl::meta::AddDeferredInterfaceBinding, fruit::impl::meta::Type<Bar>, fruit::impl::meta::Type<BarImpl> >::type, fruit::impl::meta::ComponentFunctor::apply<fruit::impl::meta::RegisterFactory, fruit::impl::meta::Type<std::unique_ptr<BarImpl, std::default_delete<BarImpl> >(fruit::Assisted<std::unique_ptr<Qux, std::default_delete<Qux> >&>)>, fruit::impl::meta::Type<getBarFactoryComponent()::<lambda(std::unique_ptr<Qux, std::default_delete<Qux> >&)> > >::type>::type, fruit::impl::meta::ProcessDeferredBindings>::type; F2 = fruit::impl::meta::ComponentFunctor::apply<fruit::impl::meta::ConvertComponent, fruit::impl::meta::Comp<fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<fruit::impl::meta::Type<std::function<std::unique_ptr<Bar, std::default_delete<Bar> >(std::unique_ptr<Qux, std::default_delete<Qux> >&)> > >, fruit::impl::meta::Vector<fruit::impl::meta::Type<std::function<std::unique_ptr<Bar, std::default_delete<Bar> >(std::unique_ptr<Qux, std::default_delete<Qux> >&)> > >, fruit::impl::meta::Vector<fruit::impl::meta::Pair<fruit::impl::meta::Type<std::function<std::unique_ptr<Bar, std::default_delete<Bar> >(std::unique_ptr<Qux, std::default_delete<Qux> >&)> >, fruit::impl::meta::Vector<> > >, fruit::impl::meta::Vector<>, fruit::impl::meta::EmptyList> >::type]’
/home/me/workspace/test2/fruit/include/fruit/impl/component.defn.h:66:7:   required from ‘fruit::Component<Types>::Component(fruit::PartialComponent<Bindings ...>&&) [with Bindings = {fruit::impl::RegisterFactory<std::unique_ptr<BarImpl, std::default_delete<BarImpl> >(fruit::Assisted<std::unique_ptr<Qux, std::default_delete<Qux> >&>), getBarFactoryComponent()::<lambda(std::unique_ptr<Qux, std::default_delete<Qux> >&)> >, fruit::impl::Bind<Bar, BarImpl>}; Params = {std::function<std::unique_ptr<Bar, std::default_delete<Bar> >(std::unique_ptr<Qux, std::default_delete<Qux> >&)>}]’
main.cpp:53:18:   required from here
/home/me/workspace/test2/fruit/include/fruit/impl/component_functors.defn.h:442:50: error: no matching function for call to ‘std::tuple<std::unique_ptr<Qux, std::default_delete<Qux> >&>::tuple(<brace-enclosed initializer list>)’
  442 |             std::tuple<NakedUserProvidedArgs...> user_provided_args{std::move(params)...};
      |                                                  ^~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/9/functional:54,
                 from main.cpp:2:
/usr/include/c++/9/tuple:808:11: note: candidate: ‘template<class _Alloc, class _Dummy, class ... _UElements, typename std::enable_if<((std::tuple<std::unique_ptr<Qux, std::default_delete<Qux> >&>::_TMCT<_UElements ...>::_MoveConstructibleTuple<_UElements ...>() && (! std::tuple<std::unique_ptr<Qux, std::default_delete<Qux> >&>::_TMCT<_UElements ...>::_ImplicitlyMoveConvertibleTuple<_UElements ...>())) && std::tuple<std::unique_ptr<Qux, std::default_delete<Qux> >&>::_TNTC<_Dummy>::_NonNestedTuple<tuple<_Tail ...>&&>()), bool>::type <anonymous> > std::tuple<_Elements>::tuple(std::allocator_arg_t, const _Alloc&, std::tuple<_Args2 ...>&&)’
  808 |  explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
      |           ^~~~~
/usr/include/c++/9/tuple:808:11: note:   template argument deduction/substitution failed:
In file included from /home/me/workspace/test2/fruit/include/fruit/component.h:25,
                 from /home/me/workspace/test2/fruit/include/fruit/fruit.h:27,
                 from main.cpp:5:
/home/me/workspace/test2/fruit/include/fruit/impl/component_functors.defn.h:442:50: note:   candidate expects 3 arguments, 1 provided
  442 |             std::tuple<NakedUserProvidedArgs...> user_provided_args{std::move(params)...};
      |                                                  ^~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/9/functional:54,
                 from main.cpp:2:
/usr/include/c++/9/tuple:793:2: note: candidate: ‘template<class _Alloc, class _Dummy, class ... _UElements, typename std::enable_if<((std::tuple<std::unique_ptr<Qux, std::default_delete<Qux> >&>::_TMCT<_UElements ...>::_MoveConstructibleTuple<_UElements ...>() && std::tuple<std::unique_ptr<Qux, std::default_delete<Qux> >&>::_TMCT<_UElements ...>::_ImplicitlyMoveConvertibleTuple<_UElements ...>()) && std::tuple<std::unique_ptr<Qux, std::default_delete<Qux> >&>::_TNTC<_Dummy>::_NonNestedTuple<tuple<_Tail ...>&&>()), bool>::type <anonymous> > std::tuple<_Elements>::tuple(std::allocator_arg_t, const _Alloc&, std::tuple<_Args2 ...>&&)’
  793 |  tuple(allocator_arg_t __tag, const _Alloc& __a,
      |  ^~~~~
/usr/include/c++/9/tuple:793:2: note:   template argument deduction/substitution failed:
In file included from /home/me/workspace/test2/fruit/include/fruit/component.h:25,
                 from /home/me/workspace/test2/fruit/include/fruit/fruit.h:27,
                 from main.cpp:5:
/home/me/workspace/test2/fruit/include/fruit/impl/component_functors.defn.h:442:50: note:   candidate expects 3 arguments, 1 provided
  442 |             std::tuple<NakedUserProvidedArgs...> user_provided_args{std::move(params)...};
      |                                                  ^~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/9/functional:54,
                 from main.cpp:2:
/usr/include/c++/9/tuple:778:11: note: candidate: ‘template<class _Alloc, class _Dummy, class ... _UElements, typename std::enable_if<((std::tuple<std::unique_ptr<Qux, std::default_delete<Qux> >&>::_TMCT<_UElements ...>::_ConstructibleTuple<_UElements ...>() && (! std::tuple<std::unique_ptr<Qux, std::default_delete<Qux> >&>::_TMCT<_UElements ...>::_ImplicitlyConvertibleTuple<_UElements ...>())) && std::tuple<std::unique_ptr<Qux, std::default_delete<Qux> >&>::_TNTC<_Dummy>::_NonNestedTuple<const tuple<_Tail ...>&>()), bool>::type <anonymous> > std::tuple<_Elements>::tuple(std::allocator_arg_t, const _Alloc&, const std::tuple<_Args2 ...>&)’
  778 |  explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
      |           ^~~~~
/usr/include/c++/9/tuple:778:11: note:   template argument deduction/substitution failed:
In file included from /home/me/workspace/test2/fruit/include/fruit/component.h:25,
                 from /home/me/workspace/test2/fruit/include/fruit/fruit.h:27,
                 from main.cpp:5:
/home/me/workspace/test2/fruit/include/fruit/impl/component_functors.defn.h:442:50: note:   candidate expects 3 arguments, 1 provided
  442 |             std::tuple<NakedUserProvidedArgs...> user_provided_args{std::move(params)...};
      |                                                  ^~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/9/functional:54,
                 from main.cpp:2:
/usr/include/c++/9/tuple:763:2: note: candidate: ‘template<class _Alloc, class _Dummy, class ... _UElements, typename std::enable_if<((std::tuple<std::unique_ptr<Qux, std::default_delete<Qux> >&>::_TMCT<_UElements ...>::_ConstructibleTuple<_UElements ...>() && std::tuple<std::unique_ptr<Qux, std::default_delete<Qux> >&>::_TMCT<_UElements ...>::_ImplicitlyConvertibleTuple<_UElements ...>()) && std::tuple<std::unique_ptr<Qux, std::default_delete<Qux> >&>::_TNTC<_Dummy>::_NonNestedTuple<const tuple<_Tail ...>&>()), bool>::type <anonymous> > std::tuple<_Elements>::tuple(std::allocator_arg_t, const _Alloc&, const std::tuple<_Args2 ...>&)’
  763 |  tuple(allocator_arg_t __tag, const _Alloc& __a,
      |  ^~~~~
/usr/include/c++/9/tuple:763:2: note:   template argument deduction/substitution failed:
In file included from /home/me/workspace/test2/fruit/include/fruit/component.h:25,
                 from /home/me/workspace/test2/fruit/include/fruit/fruit.h:27,
                 from main.cpp:5:
/home/me/workspace/test2/fruit/include/fruit/impl/component_functors.defn.h:442:50: note:   candidate expects 3 arguments, 1 provided
  442 |             std::tuple<NakedUserProvidedArgs...> user_provided_args{std::move(params)...};
      |                                                  ^~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/9/functional:54,
                 from main.cpp:2:
/usr/include/c++/9/tuple:751:2: note: candidate: ‘template<class _Alloc> std::tuple<_Elements>::tuple(std::allocator_arg_t, const _Alloc&, std::tuple<_Elements>&&)’
  751 |  tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in)
      |  ^~~~~
/usr/include/c++/9/tuple:751:2: note:   template argument deduction/substitution failed:
In file included from /home/me/workspace/test2/fruit/include/fruit/component.h:25,
                 from /home/me/workspace/test2/fruit/include/fruit/fruit.h:27,
                 from main.cpp:5:
/home/me/workspace/test2/fruit/include/fruit/impl/component_functors.defn.h:442:50: note:   candidate expects 3 arguments, 1 provided
  442 |             std::tuple<NakedUserProvidedArgs...> user_provided_args{std::move(params)...};
      |                                                  ^~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/9/functional:54,
                 from main.cpp:2:
/usr/include/c++/9/tuple:747:2: note: candidate: ‘template<class _Alloc> std::tuple<_Elements>::tuple(std::allocator_arg_t, const _Alloc&, const std::tuple<_Elements>&)’
  747 |  tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in)
      |  ^~~~~
/usr/include/c++/9/tuple:747:2: note:   template argument deduction/substitution failed:
In file included from /home/me/workspace/test2/fruit/include/fruit/component.h:25,
                 from /home/me/workspace/test2/fruit/include/fruit/fruit.h:27,
                 from main.cpp:5:
/home/me/workspace/test2/fruit/include/fruit/impl/component_functors.defn.h:442:50: note:   candidate expects 3 arguments, 1 provided
  442 |             std::tuple<NakedUserProvidedArgs...> user_provided_args{std::move(params)...};
      |                                                  ^~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/9/functional:54,
                 from main.cpp:2:
/usr/include/c++/9/tuple:741:11: note: candidate: ‘template<class _Alloc, class ... _UElements, typename std::enable_if<(std::tuple<std::unique_ptr<Qux, std::default_delete<Qux> >&>::_TMC<_UElements ...>::_MoveConstructibleTuple<_UElements ...>() && (! std::tuple<std::unique_ptr<Qux, std::default_delete<Qux> >&>::_TMC<_UElements ...>::_ImplicitlyMoveConvertibleTuple<_UElements ...>())), bool>::type <anonymous> > std::tuple<_Elements>::tuple(std::allocator_arg_t, const _Alloc&, _UElements&& ...)’
  741 |  explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
      |           ^~~~~
/usr/include/c++/9/tuple:741:11: note:   template argument deduction/substitution failed:
In file included from /home/me/workspace/test2/fruit/include/fruit/component.h:25,
                 from /home/me/workspace/test2/fruit/include/fruit/fruit.h:27,
                 from main.cpp:5:
/home/me/workspace/test2/fruit/include/fruit/impl/component_functors.defn.h:442:50: note:   candidate expects at least 2 arguments, 1 provided
  442 |             std::tuple<NakedUserProvidedArgs...> user_provided_args{std::move(params)...};
      |                                                  ^~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/9/functional:54,
                 from main.cpp:2:
/usr/include/c++/9/tuple:730:2: note: candidate: ‘template<class _Alloc, class ... _UElements, typename std::enable_if<(std::tuple<std::unique_ptr<Qux, std::default_delete<Qux> >&>::_TMC<_UElements ...>::_MoveConstructibleTuple<_UElements ...>() && std::tuple<std::unique_ptr<Qux, std::default_delete<Qux> >&>::_TMC<_UElements ...>::_ImplicitlyMoveConvertibleTuple<_UElements ...>()), bool>::type <anonymous> > std::tuple<_Elements>::tuple(std::allocator_arg_t, const _Alloc&, _UElements&& ...)’
  730 |  tuple(allocator_arg_t __tag, const _Alloc& __a,
      |  ^~~~~
/usr/include/c++/9/tuple:730:2: note:   template argument deduction/substitution failed:
In file included from /home/me/workspace/test2/fruit/include/fruit/component.h:25,
                 from /home/me/workspace/test2/fruit/include/fruit/fruit.h:27,
                 from main.cpp:5:
/home/me/workspace/test2/fruit/include/fruit/impl/component_functors.defn.h:442:50: note:   candidate expects at least 2 arguments, 1 provided
  442 |             std::tuple<NakedUserProvidedArgs...> user_provided_args{std::move(params)...};
      |                                                  ^~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/9/functional:54,
                 from main.cpp:2:
/usr/include/c++/9/tuple:720:11: note: candidate: ‘template<class _Alloc, class _Dummy, typename std::enable_if<(std::tuple<std::unique_ptr<Qux, std::default_delete<Qux> >&>::_TCC<_Dummy>::_ConstructibleTuple<unique_ptr<Qux, std::default_delete<Qux> >&>() && (! std::tuple<std::unique_ptr<Qux, std::default_delete<Qux> >&>::_TCC<_Dummy>::_ImplicitlyConvertibleTuple<unique_ptr<Qux, std::default_delete<Qux> >&>())), bool>::type <anonymous> > std::tuple<_Elements>::tuple(std::allocator_arg_t, const _Alloc&, const _Elements& ...)’
  720 |  explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
      |           ^~~~~
/usr/include/c++/9/tuple:720:11: note:   template argument deduction/substitution failed:
In file included from /home/me/workspace/test2/fruit/include/fruit/component.h:25,
                 from /home/me/workspace/test2/fruit/include/fruit/fruit.h:27,
                 from main.cpp:5:
/home/me/workspace/test2/fruit/include/fruit/impl/component_functors.defn.h:442:50: note:   candidate expects 3 arguments, 1 provided
  442 |             std::tuple<NakedUserProvidedArgs...> user_provided_args{std::move(params)...};
      |                                                  ^~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/9/functional:54,
                 from main.cpp:2:
/usr/include/c++/9/tuple:709:2: note: candidate: ‘template<class _Alloc, class _Dummy, typename std::enable_if<(std::tuple<std::unique_ptr<Qux, std::default_delete<Qux> >&>::_TCC<_Dummy>::_ConstructibleTuple<unique_ptr<Qux, std::default_delete<Qux> >&>() && std::tuple<std::unique_ptr<Qux, std::default_delete<Qux> >&>::_TCC<_Dummy>::_ImplicitlyConvertibleTuple<unique_ptr<Qux, std::default_delete<Qux> >&>()), bool>::type <anonymous> > std::tuple<_Elements>::tuple(std::allocator_arg_t, const _Alloc&, const _Elements& ...)’
  709 |  tuple(allocator_arg_t __tag, const _Alloc& __a,
      |  ^~~~~
/usr/include/c++/9/tuple:709:2: note:   template argument deduction/substitution failed:
In file included from /home/me/workspace/test2/fruit/include/fruit/component.h:25,
                 from /home/me/workspace/test2/fruit/include/fruit/fruit.h:27,
                 from main.cpp:5:
/home/me/workspace/test2/fruit/include/fruit/impl/component_functors.defn.h:442:50: note:   candidate expects 3 arguments, 1 provided
  442 |             std::tuple<NakedUserProvidedArgs...> user_provided_args{std::move(params)...};
      |                                                  ^~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/9/functional:54,
                 from main.cpp:2:
/usr/include/c++/9/tuple:699:2: note: candidate: ‘template<class _Alloc> std::tuple<_Elements>::tuple(std::allocator_arg_t, const _Alloc&)’
  699 |  tuple(allocator_arg_t __tag, const _Alloc& __a)
      |  ^~~~~
/usr/include/c++/9/tuple:699:2: note:   template argument deduction/substitution failed:
In file included from /home/me/workspace/test2/fruit/include/fruit/component.h:25,
                 from /home/me/workspace/test2/fruit/include/fruit/fruit.h:27,
                 from main.cpp:5:
/home/me/workspace/test2/fruit/include/fruit/impl/component_functors.defn.h:442:50: note:   candidate expects 2 arguments, 1 provided
  442 |             std::tuple<NakedUserProvidedArgs...> user_provided_args{std::move(params)...};
      |                                                  ^~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/9/functional:54,
                 from main.cpp:2:
/usr/include/c++/9/tuple:693:28: note: candidate: ‘template<class ... _UElements, class _Dummy, typename std::enable_if<((std::tuple<std::unique_ptr<Qux, std::default_delete<Qux> >&>::_TMCT<_UElements ...>::_MoveConstructibleTuple<_UElements ...>() && (! std::tuple<std::unique_ptr<Qux, std::default_delete<Qux> >&>::_TMCT<_UElements ...>::_ImplicitlyMoveConvertibleTuple<_UElements ...>())) && std::tuple<std::unique_ptr<Qux, std::default_delete<Qux> >&>::_TNTC<_Dummy>::_NonNestedTuple<tuple<_Tps ...>&&>()), bool>::type <anonymous> > constexpr std::tuple<_Elements>::tuple(std::tuple<_Args1 ...>&&)’
  693 |         explicit constexpr tuple(tuple<_UElements...>&& __in)
      |                            ^~~~~
/usr/include/c++/9/tuple:693:28: note:   template argument deduction/substitution failed:
In file included from /home/me/workspace/test2/fruit/include/fruit/component.h:25,
                 from /home/me/workspace/test2/fruit/include/fruit/fruit.h:27,
                 from main.cpp:5:
/home/me/workspace/test2/fruit/include/fruit/impl/component_functors.defn.h:442:50: note:   ‘std::remove_reference<std::unique_ptr<Qux>&>::type’ {aka ‘std::unique_ptr<Qux>’} is not derived from ‘std::tuple<_Tps ...>’
  442 |             std::tuple<NakedUserProvidedArgs...> user_provided_args{std::move(params)...};
      |                                                  ^~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/9/functional:54,
                 from main.cpp:2:
/usr/include/c++/9/tuple:682:19: note: candidate: ‘template<class ... _UElements, class _Dummy, typename std::enable_if<((std::tuple<std::unique_ptr<Qux, std::default_delete<Qux> >&>::_TMCT<_UElements ...>::_MoveConstructibleTuple<_UElements ...>() && std::tuple<std::unique_ptr<Qux, std::default_delete<Qux> >&>::_TMCT<_UElements ...>::_ImplicitlyMoveConvertibleTuple<_UElements ...>()) && std::tuple<std::unique_ptr<Qux, std::default_delete<Qux> >&>::_TNTC<_Dummy>::_NonNestedTuple<tuple<_Tps ...>&&>()), bool>::type <anonymous> > constexpr std::tuple<_Elements>::tuple(std::tuple<_Args1 ...>&&)’
  682 |         constexpr tuple(tuple<_UElements...>&& __in)
      |                   ^~~~~
/usr/include/c++/9/tuple:682:19: note:   template argument deduction/substitution failed:
In file included from /home/me/workspace/test2/fruit/include/fruit/component.h:25,
                 from /home/me/workspace/test2/fruit/include/fruit/fruit.h:27,
                 from main.cpp:5:
/home/me/workspace/test2/fruit/include/fruit/impl/component_functors.defn.h:442:50: note:   ‘std::remove_reference<std::unique_ptr<Qux>&>::type’ {aka ‘std::unique_ptr<Qux>’} is not derived from ‘std::tuple<_Tps ...>’
  442 |             std::tuple<NakedUserProvidedArgs...> user_provided_args{std::move(params)...};
      |                                                  ^~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/9/functional:54,
                 from main.cpp:2:
/usr/include/c++/9/tuple:670:28: note: candidate: ‘template<class ... _UElements, class _Dummy, typename std::enable_if<((std::tuple<std::unique_ptr<Qux, std::default_delete<Qux> >&>::_TMCT<_UElements ...>::_ConstructibleTuple<_UElements ...>() && (! std::tuple<std::unique_ptr<Qux, std::default_delete<Qux> >&>::_TMCT<_UElements ...>::_ImplicitlyConvertibleTuple<_UElements ...>())) && std::tuple<std::unique_ptr<Qux, std::default_delete<Qux> >&>::_TNTC<_Dummy>::_NonNestedTuple<const tuple<_Tps ...>&>()), bool>::type <anonymous> > constexpr std::tuple<_Elements>::tuple(const std::tuple<_Args1 ...>&)’
  670 |         explicit constexpr tuple(const tuple<_UElements...>& __in)
      |                            ^~~~~
/usr/include/c++/9/tuple:670:28: note:   template argument deduction/substitution failed:
In file included from /home/me/workspace/test2/fruit/include/fruit/component.h:25,
                 from /home/me/workspace/test2/fruit/include/fruit/fruit.h:27,
                 from main.cpp:5:
/home/me/workspace/test2/fruit/include/fruit/impl/component_functors.defn.h:442:50: note:   ‘std::remove_reference<std::unique_ptr<Qux>&>::type’ {aka ‘std::unique_ptr<Qux>’} is not derived from ‘const std::tuple<_Tps ...>’
  442 |             std::tuple<NakedUserProvidedArgs...> user_provided_args{std::move(params)...};
      |                                                  ^~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/9/functional:54,
                 from main.cpp:2:
/usr/include/c++/9/tuple:658:19: note: candidate: ‘template<class ... _UElements, class _Dummy, typename std::enable_if<((std::tuple<std::unique_ptr<Qux, std::default_delete<Qux> >&>::_TMCT<_UElements ...>::_ConstructibleTuple<_UElements ...>() && std::tuple<std::unique_ptr<Qux, std::default_delete<Qux> >&>::_TMCT<_UElements ...>::_ImplicitlyConvertibleTuple<_UElements ...>()) && std::tuple<std::unique_ptr<Qux, std::default_delete<Qux> >&>::_TNTC<_Dummy>::_NonNestedTuple<const tuple<_Tps ...>&>()), bool>::type <anonymous> > constexpr std::tuple<_Elements>::tuple(const std::tuple<_Args1 ...>&)’
  658 |         constexpr tuple(const tuple<_UElements...>& __in)
      |                   ^~~~~
/usr/include/c++/9/tuple:658:19: note:   template argument deduction/substitution failed:
In file included from /home/me/workspace/test2/fruit/include/fruit/component.h:25,
                 from /home/me/workspace/test2/fruit/include/fruit/fruit.h:27,
                 from main.cpp:5:
/home/me/workspace/test2/fruit/include/fruit/impl/component_functors.defn.h:442:50: note:   ‘std::remove_reference<std::unique_ptr<Qux>&>::type’ {aka ‘std::unique_ptr<Qux>’} is not derived from ‘const std::tuple<_Tps ...>’
  442 |             std::tuple<NakedUserProvidedArgs...> user_provided_args{std::move(params)...};
      |                                                  ^~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/9/functional:54,
                 from main.cpp:2:
/usr/include/c++/9/tuple:642:17: note: candidate: ‘constexpr std::tuple<_Elements>::tuple(std::tuple<_Elements>&&) [with _Elements = {std::unique_ptr<Qux, std::default_delete<Qux> >&}]’
  642 |       constexpr tuple(tuple&&) = default;
      |                 ^~~~~
/usr/include/c++/9/tuple:642:23: note:   no known conversion for argument 1 from ‘std::remove_reference<std::unique_ptr<Qux>&>::type’ {aka ‘std::unique_ptr<Qux>’} to ‘std::tuple<std::unique_ptr<Qux, std::default_delete<Qux> >&>&&’
  642 |       constexpr tuple(tuple&&) = default;
      |                       ^~~~~~~
/usr/include/c++/9/tuple:640:17: note: candidate: ‘constexpr std::tuple<_Elements>::tuple(const std::tuple<_Elements>&) [with _Elements = {std::unique_ptr<Qux, std::default_delete<Qux> >&}]’
  640 |       constexpr tuple(const tuple&) = default;
      |                 ^~~~~
/usr/include/c++/9/tuple:640:23: note:   no known conversion for argument 1 from ‘std::remove_reference<std::unique_ptr<Qux>&>::type’ {aka ‘std::unique_ptr<Qux>’} to ‘const std::tuple<std::unique_ptr<Qux, std::default_delete<Qux> >&>&’
  640 |       constexpr tuple(const tuple&) = default;
      |                       ^~~~~~~~~~~~
/usr/include/c++/9/tuple:637:28: note: candidate: ‘template<class ... _UElements, typename std::enable_if<((std::tuple<std::unique_ptr<Qux, std::default_delete<Qux> >&>::_TMC<_UElements ...>::_MoveConstructibleTuple<_UElements ...>() && (! std::tuple<std::unique_ptr<Qux, std::default_delete<Qux> >&>::_TMC<_UElements ...>::_ImplicitlyMoveConvertibleTuple<_UElements ...>())) && (1 >= 1)), bool>::type <anonymous> > constexpr std::tuple<_Elements>::tuple(_UElements&& ...)’
  637 |         explicit constexpr tuple(_UElements&&... __elements)
      |                            ^~~~~
/usr/include/c++/9/tuple:637:28: note:   template argument deduction/substitution failed:
/usr/include/c++/9/tuple:636:21: error: no type named ‘type’ in ‘struct std::enable_if<false, bool>’
  636 |         bool>::type=false>
      |                     ^~~~~
/usr/include/c++/9/tuple:626:19: note: candidate: ‘template<class ... _UElements, typename std::enable_if<((std::tuple<std::unique_ptr<Qux, std::default_delete<Qux> >&>::_TMC<_UElements ...>::_MoveConstructibleTuple<_UElements ...>() && std::tuple<std::unique_ptr<Qux, std::default_delete<Qux> >&>::_TMC<_UElements ...>::_ImplicitlyMoveConvertibleTuple<_UElements ...>()) && (1 >= 1)), bool>::type <anonymous> > constexpr std::tuple<_Elements>::tuple(_UElements&& ...)’
  626 |         constexpr tuple(_UElements&&... __elements)
      |                   ^~~~~
/usr/include/c++/9/tuple:626:19: note:   template argument deduction/substitution failed:
/usr/include/c++/9/tuple:625:21: error: no type named ‘type’ in ‘struct std::enable_if<false, bool>’
  625 |         bool>::type=true>
      |                     ^~~~
/usr/include/c++/9/tuple:599:26: note: candidate: ‘template<class _Dummy, typename std::enable_if<((std::tuple<std::unique_ptr<Qux, std::default_delete<Qux> >&>::_TCC<_Dummy>::_ConstructibleTuple<unique_ptr<Qux, std::default_delete<Qux> >&>() && (! std::tuple<std::unique_ptr<Qux, std::default_delete<Qux> >&>::_TCC<_Dummy>::_ImplicitlyConvertibleTuple<unique_ptr<Qux, std::default_delete<Qux> >&>())) && (1 >= 1)), bool>::type <anonymous> > constexpr std::tuple<_Elements>::tuple(const _Elements& ...)’
  599 |       explicit constexpr tuple(const _Elements&... __elements)
      |                          ^~~~~
/usr/include/c++/9/tuple:599:26: note:   template argument deduction/substitution failed:
/usr/include/c++/9/tuple:598:28: error: no type named ‘type’ in ‘struct std::enable_if<false, bool>’
  598 |                bool>::type=false>
      |                            ^~~~~
/usr/include/c++/9/tuple:588:19: note: candidate: ‘template<class _Dummy, typename std::enable_if<((std::tuple<std::unique_ptr<Qux, std::default_delete<Qux> >&>::_TCC<_Dummy>::_ConstructibleTuple<unique_ptr<Qux, std::default_delete<Qux> >&>() && std::tuple<std::unique_ptr<Qux, std::default_delete<Qux> >&>::_TCC<_Dummy>::_ImplicitlyConvertibleTuple<unique_ptr<Qux, std::default_delete<Qux> >&>()) && (1 >= 1)), bool>::type <anonymous> > constexpr std::tuple<_Elements>::tuple(const _Elements& ...)’
  588 |         constexpr tuple(const _Elements&... __elements)
      |                   ^~~~~
/usr/include/c++/9/tuple:588:19: note:   template argument deduction/substitution failed:
In file included from /home/me/workspace/test2/fruit/include/fruit/component.h:25,
                 from /home/me/workspace/test2/fruit/include/fruit/fruit.h:27,
                 from main.cpp:5:
/home/me/workspace/test2/fruit/include/fruit/impl/component_functors.defn.h:442:50: note:   cannot convert ‘std::move<std::unique_ptr<Qux>&>((* & params#0))’ (type ‘std::remove_reference<std::unique_ptr<Qux>&>::type’ {aka ‘std::unique_ptr<Qux>’}) to type ‘std::unique_ptr<Qux>&’
  442 |             std::tuple<NakedUserProvidedArgs...> user_provided_args{std::move(params)...};
      |                                                  ^~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/9/functional:54,
                 from main.cpp:2:
/usr/include/c++/9/tuple:571:26: note: candidate: ‘template<class _Dummy, typename std::enable_if<(std::tuple<std::unique_ptr<Qux, std::default_delete<Qux> >&>::_TC2<_Dummy>::_DefaultConstructibleTuple() && (! std::tuple<std::unique_ptr<Qux, std::default_delete<Qux> >&>::_TC2<_Dummy>::_ImplicitlyDefaultConstructibleTuple())), bool>::type <anonymous> > constexpr std::tuple<_Elements>::tuple()’
  571 |       explicit constexpr tuple()
      |                          ^~~~~
/usr/include/c++/9/tuple:571:26: note:   template argument deduction/substitution failed:
In file included from /home/me/workspace/test2/fruit/include/fruit/component.h:25,
                 from /home/me/workspace/test2/fruit/include/fruit/fruit.h:27,
                 from main.cpp:5:
/home/me/workspace/test2/fruit/include/fruit/impl/component_functors.defn.h:442:50: note:   candidate expects 0 arguments, 1 provided
  442 |             std::tuple<NakedUserProvidedArgs...> user_provided_args{std::move(params)...};
      |                                                  ^~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/9/functional:54,
                 from main.cpp:2:
/usr/include/c++/9/tuple:561:17: note: candidate: ‘template<class _Dummy, typename std::enable_if<std::tuple<std::unique_ptr<Qux, std::default_delete<Qux> >&>::_TC2<_Dummy>::_ImplicitlyDefaultConstructibleTuple(), bool>::type <anonymous> > constexpr std::tuple<_Elements>::tuple()’
  561 |       constexpr tuple()
      |                 ^~~~~
/usr/include/c++/9/tuple:561:17: note:   template argument deduction/substitution failed:
In file included from /home/me/workspace/test2/fruit/include/fruit/component.h:25,
                 from /home/me/workspace/test2/fruit/include/fruit/fruit.h:27,
                 from main.cpp:5:
/home/me/workspace/test2/fruit/include/fruit/impl/component_functors.defn.h:442:50: note:   candidate expects 0 arguments, 1 provided
  442 |             std::tuple<NakedUserProvidedArgs...> user_provided_args{std::move(params)...};
      |                                                  ^~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/9/functional:59,
                 from main.cpp:2:
/usr/include/c++/9/bits/std_function.h:667:7: error: ‘std::function<_Res(_ArgTypes ...)>::function(_Functor) [with _Functor = fruit::impl::meta::RegisterFactoryHelper::apply<Comp, DecoratedSignature, Lambda, fruit::impl::meta::Type<NakedC(NakedUserProvidedArgs ...)>, fruit::impl::meta::Type<NakedC(NakedAllArgs ...)>, fruit::impl::meta::Vector<InjectedAnnotatedArgs ...>, fruit::impl::meta::Vector<fruit::impl::meta::Type<NakedInjectedArgs>...>, fruit::impl::meta::Vector<Indexes ...> >::Op::operator()(fruit::impl::FixedSizeVector<fruit::impl::ComponentStorageEntry>&) [with Comp = fruit::impl::meta::Comp<fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<fruit::impl::meta::Pair<fruit::impl::meta::Type<Bar>, fruit::impl::meta::Type<BarImpl> > >, fruit::impl::meta::EmptyList>; DecoratedSignature = fruit::impl::meta::Type<std::unique_ptr<BarImpl>(fruit::Assisted<std::unique_ptr<Qux>&>)>; Lambda = fruit::impl::meta::Type<getBarFactoryComponent()::<lambda(std::unique_ptr<Qux>&)> >; NakedC = std::unique_ptr<BarImpl>; NakedUserProvidedArgs = {std::unique_ptr<Qux, std::default_delete<Qux> >&}; NakedAllArgs = {std::unique_ptr<Qux, std::default_delete<Qux> >&}; InjectedAnnotatedArgs = {}; NakedInjectedArgs = {}; Indexes = {fruit::impl::meta::Int<0>}]::<lambda()>::<lambda(std::unique_ptr<Qux>&)>; <template-parameter-2-2> = void; <template-parameter-2-3> = void; _Res = std::unique_ptr<BarImpl>; _ArgTypes = {std::unique_ptr<Qux, std::default_delete<Qux> >&}]’, declared using local type ‘fruit::impl::meta::RegisterFactoryHelper::apply<Comp, DecoratedSignature, Lambda, fruit::impl::meta::Type<NakedC(NakedUserProvidedArgs ...)>, fruit::impl::meta::Type<NakedC(NakedAllArgs ...)>, fruit::impl::meta::Vector<InjectedAnnotatedArgs ...>, fruit::impl::meta::Vector<fruit::impl::meta::Type<NakedInjectedArgs>...>, fruit::impl::meta::Vector<Indexes ...> >::Op::operator()(fruit::impl::FixedSizeVector<fruit::impl::ComponentStorageEntry>&) [with Comp = fruit::impl::meta::Comp<fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<fruit::impl::meta::Pair<fruit::impl::meta::Type<Bar>, fruit::impl::meta::Type<BarImpl> > >, fruit::impl::meta::EmptyList>; DecoratedSignature = fruit::impl::meta::Type<std::unique_ptr<BarImpl>(fruit::Assisted<std::unique_ptr<Qux>&>)>; Lambda = fruit::impl::meta::Type<getBarFactoryComponent()::<lambda(std::unique_ptr<Qux>&)> >; NakedC = std::unique_ptr<BarImpl>; NakedUserProvidedArgs = {std::unique_ptr<Qux, std::default_delete<Qux> >&}; NakedAllArgs = {std::unique_ptr<Qux, std::default_delete<Qux> >&}; InjectedAnnotatedArgs = {}; NakedInjectedArgs = {}; Indexes = {fruit::impl::meta::Int<0>}]::<lambda()>::<lambda(std::unique_ptr<Qux>&)>’, is used but never defined [-fpermissive]
  667 |       function<_Res(_ArgTypes...)>::
      |       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /home/me/workspace/test2/fruit/include/fruit/impl/injector/injector_storage.h:285,
                 from /home/me/workspace/test2/fruit/include/fruit/impl/component_functors.defn.h:24,
                 from /home/me/workspace/test2/fruit/include/fruit/component.h:25,
                 from /home/me/workspace/test2/fruit/include/fruit/fruit.h:27,
                 from main.cpp:5:
/home/me/workspace/test2/fruit/include/fruit/impl/injector/injector_storage.defn.h:602:30: warning: ‘static fruit::impl::ComponentStorageEntry fruit::impl::InjectorStorage::createComponentStorageEntryForProvider() [with AnnotatedSignature = std::function<std::unique_ptr<BarImpl>(std::unique_ptr<Qux>&)>(); Lambda = fruit::impl::meta::RegisterFactoryHelper::apply<Comp, DecoratedSignature, Lambda, fruit::impl::meta::Type<NakedC(NakedUserProvidedArgs ...)>, fruit::impl::meta::Type<NakedC(NakedAllArgs ...)>, fruit::impl::meta::Vector<InjectedAnnotatedArgs ...>, fruit::impl::meta::Vector<fruit::impl::meta::Type<NakedInjectedArgs>...>, fruit::impl::meta::Vector<Indexes ...> >::Op::operator()(fruit::impl::FixedSizeVector<fruit::impl::ComponentStorageEntry>&) [with Comp = fruit::impl::meta::Comp<fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<>, fruit::impl::meta::Vector<fruit::impl::meta::Pair<fruit::impl::meta::Type<Bar>, fruit::impl::meta::Type<BarImpl> > >, fruit::impl::meta::EmptyList>; DecoratedSignature = fruit::impl::meta::Type<std::unique_ptr<BarImpl>(fruit::Assisted<std::unique_ptr<Qux>&>)>; Lambda = fruit::impl::meta::Type<getBarFactoryComponent()::<lambda(std::unique_ptr<Qux>&)> >; NakedC = std::unique_ptr<BarImpl>; NakedUserProvidedArgs = {std::unique_ptr<Qux, std::default_delete<Qux> >&}; NakedAllArgs = {std::unique_ptr<Qux, std::default_delete<Qux> >&}; InjectedAnnotatedArgs = {}; NakedInjectedArgs = {}; Indexes = {fruit::impl::meta::Int<0>}]::<lambda()>]’ used but never defined
  602 | inline ComponentStorageEntry InjectorStorage::createComponentStorageEntryForProvider() {
      |

@tt4g
Copy link
Contributor

tt4g commented Sep 23, 2020

Probably because std::move(std::unique_ptr<T>) has not been called inside fruit, so std::unique_ptr is copied.

The fruit template class is so complex that it would take me a long time to identify the cause.

I'm sorry, but I can't be of any further help.

@poletti-marco
Copy link
Contributor

poletti-marco commented Sep 24, 2020 via email

@dfontenot
Copy link
Author

@tt4g thanks for taking a look I appreciate it

@poletti-marco that would be awesome, thank you!

@poletti-marco
Copy link
Contributor

Hi, sorry for the delay.
I tried again today with the code from your first comment in this thread with Fruit master and it seems to work.
So maybe you used a different version?

See https://github.com/google/fruit/wiki/install#building-fruit-manually in case you haven't seen that yet.

If that's what you did, can you post more information on your system?
Specifically:

  • What compiler you're using, and what version
  • C++ language version (from your examples I imagine it's at least C++14)
  • Platform (Linux, Windows, OS X, ...)

My fix commit seems to have caused an error in CI on Windows with Visual Studio, I'll look into that but your error messages don't look like Visual Studio ones anyway.

@dfontenot
Copy link
Author

I've been building locally with commit 9284588

I re-tried my original code and it worked with this commit. Thanks! Sorry for the churn--I had been only trying with the latest iterations of that code. Are there any major issues with that original code?

Environment:

  • g++ (Ubuntu 9.3.0-10ubuntu2) 9.3.0
  • Ubuntu 20.04 amd64
  • Build command: g++ -Wall -Wno-switch -std=c++17 -fdiagnostics-color=always -I/home/me/workspace/test2/fruit/include main.cpp -L/home/me/workspace/test2/fruit/src -o main -lfruit

Commands I used to build Fruit:

  • cmake . -GUnix\ Makefiles -DCMAKE_BUILD_TYPE=Release -DFRUIT_USES_BOOST=False
  • make

Once again thank you for fixing the issue.

@poletti-marco
Copy link
Contributor

Are there any major issues with that original code?

Not AFAICT. It looks fine to me, and it should have worked from the start, and now it does too :-)

If there are some variants that you tried and you also expected to work, please post the exact code you tried and I can comment on those.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants