-
Notifications
You must be signed in to change notification settings - Fork 203
Open
Description
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.
Metadata
Metadata
Assignees
Labels
No labels