Bug: compilation fails for an std::function with an std::function parameter
eserg opened this issue · comments
Sergey Eliseev commented
Hi,
The use case is somewhat irregular, but I had met it actually trying to bridge a library API to Objective-C, so it's not made up.
Such construct:
class contact : public scapix::bridge::object<contact>
{
public:
using CbType = function<void(string)>;
void doAsync(function<void(CbType)> asyncOp)
{
CbType cb = [](string msg) -> void { cout << "Async op " << msg << endl; };
asyncOp(std::move(cb));
}
};
Compiled with:
cmake -B build/xcode_mac_objc -G "Xcode" -DSCAPIX_BRIDGE=objc -DSCAPIX_PLATFORM=apple
cmake --build build/xcode_mac_objc
fails with:
In file included from ~/src/scapix-test/generated/bridge/objc/bridge/bridge/Contact.mm:4:
In file included from ~/.cmodule/scapix/1.0.11/source/../../../../src/scapix-test/contact.h:1:
In file included from ~/.cmodule/scapix/1.0.11/source/scapix/bridge/object.h:11:
In file included from ~/.cmodule/scapix/1.0.11/source/scapix/bridge/objc/object.h:91:
~/.cmodule/scapix/1.0.11/source/scapix/link/objc/convert.h:32:69: error: rvalue reference to type 'function<...>' cannot bind to lvalue of type 'function<...>'
return convert<remove_cvref_t<ObjC>, remove_cvref_t<Cpp>>::objc(std::forward<Cpp>(cpp));
^~~~~~~~~~~~~~~~~~~~~~
~/.cmodule/scapix/1.0.11/source/scapix/link/objc/convert.h:406:30: note: in instantiation of function template specialization 'scapix::link::objc::convert_objc<void (^)(NSString *), std::__1::function<void
(std::__1::basic_string<char>)> &>' requested here
return value(convert_objc<ObjcArgs>(args)...);
^
~/.cmodule/scapix/1.0.11/source/scapix/link/objc/convert.h:38:64: note: in instantiation of member function 'scapix::link::objc::convert<void (^)(void (^)(NSString *)), std::__1::function<void
(std::__1::function<void (std::__1::basic_string<char>)>)>, void>::cpp' requested here
return convert<remove_cvref_t<ObjC>, remove_cvref_t<Cpp>>::cpp(std::forward<ObjC>(objc));
^
In file included from ~/src/scapix-test/generated/bridge/objc/bridge/bridge/Contact.mm:4:
In file included from ~/.cmodule/scapix/1.0.11/source/../../../../src/scapix-test/contact.h:1:
In file included from ~/.cmodule/scapix/1.0.11/source/scapix/bridge/object.h:11:
~/.cmodule/scapix/1.0.11/source/scapix/bridge/objc/object.h:212:38: note: in instantiation of function template specialization 'scapix::bridge::objc::call_impl<&tiny::contact::doAsync>::call<void, Contact, void
(^)(void (^)(NSString *))>' requested here
return call_impl<Func>::template call<ObjcRet>(args...);
^
In file included from ~/src/scapix-test/generated/bridge/objc/bridge/bridge/Contact.mm:4:
In file included from ~/.cmodule/scapix/1.0.11/source/../../../../src/scapix-test/contact.h:1:
In file included from ~/.cmodule/scapix/1.0.11/source/scapix/bridge/object.h:11:
In file included from ~/.cmodule/scapix/1.0.11/source/scapix/bridge/objc/object.h:91:
~/.cmodule/scapix/1.0.11/source/scapix/link/objc/convert.h:412:56: note: passing argument to parameter 'value' here
static block_type objc(std::function<R(Args...)>&& value)
^
1 warning and 1 error generated.
** BUILD FAILED **
The Objective-C generated wrapper looks correct, but C++ templates fail to instantiate.
The typedef/alias
for callback type does not affect the behaviour.
Sergey Eliseev commented
Thank you, it's a saviour! I couldn't find another way of doing dependency injection with Scapix.
Boris Rasin commented
I have released the version with this fix, please update to latest release.