-
Notifications
You must be signed in to change notification settings - Fork 200
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
Comments
In 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));
});
} |
@tt4g thanks, gave that a try. However, another error was introduced. It looks like
|
Sorry. I was wrong too. 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));
});
} |
With that change, looks like the standard library errors cleared up. However, some static_asserts from Fruit are now failing.
|
Apparently you have to tell fruit exactly what type the factory function will return. fruit/tests/test_register_factory.py Lines 1460 to 1512 in 4ded6e2
Try specifying 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));
});
} |
With that newest change to specify the template argument as
Also, I am confused about the need for the
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. |
It seems that 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;
}
|
The fruit needs to be internally bound to a pure virtual class and its implementation. Without the type information, when Wiki has more details: https://github.com/google/fruit/wiki/tutorial:-getting-started |
@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. |
The use of |
Perhaps this could be a feature request? |
@poletti-marco @tt4g will try using the latest master soon and will let you know. Thanks again for looking into this so quickly! |
@poletti-marco I'm still running into compilation issues on Fruit master. Here is the error.
|
@dfontenot Can you try to replace 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));
});
} |
@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.
Here is the new error
|
Probably because 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. |
I'm a bit busy during the week, but I'll look into in this weekend (since
it looks like there's an easy workaround using shared_ptr for now).
…On Wed, 23 Sep 2020, 01:36 tt4g, ***@***.***> wrote:
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.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#126 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AALZ4FYSLATPSENHUVP5ANTSHGXRXANCNFSM4RS2GBSA>
.
|
@tt4g thanks for taking a look I appreciate it @poletti-marco that would be awesome, thank you! |
Hi, sorry for the delay. 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?
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. |
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:
Commands I used to build Fruit:
Once again thank you for fixing the issue. |
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. |
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.The text was updated successfully, but these errors were encountered: