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;
}
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:
I also attempted to de-fruit-ify the library the best I could, and I was able to get a working binary from it:
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.