satoren / kaguya

C++ binding to Lua
Boost Software License 1.0
345 stars 70 forks source link

Compatibility with Boost.Bind/Boost.Phoenix #76

Open Flamefire opened 6 years ago

Flamefire commented 6 years ago

Currently it seems to be impossible to use Boost.Bind/Boost.Phoenix with kaguya. But those are required to use lambdas before C++11.

My sample usage is:

#include <boost/bind.hpp>
std::string LuaInterfaceBase::Translate(const std::string& key){...}
lua["_"] = kaguya::function(boost::bind(&LuaInterfaceBase::Translate, this, _1));

#include <boost/phoenix.hpp>
std::string LuaInterfaceBase::Translate(const std::string& key){...}
lua["_"] = kaguya::function(boost::phoenix::bind(&LuaInterfaceBase::Translate, this, boost::phoenix::placeholders::arg1));

I get the following errors:

contrib\kaguya\include\kaguya/native_function.hpp(70): error C2027: Verwendung des undefinierten Typs "kaguya::util::FunctionSignature<T,void>" with [ T=boost::_bi::bind_t<std::string,boost::_mfi::mf1<std::string,LuaInterfaceBase,const std::string &>,boost::_bi::list2<boost::_bi::value<LuaInterfaceBase >,boost::arg<1>>> ] contrib\kaguya\include\kaguya/native_function.hpp(70): note: Siehe Deklaration von "kaguya::util::FunctionSignature<T,void>" with [ T=boost::_bi::bind_t<std::string,boost::_mfi::mf1<std::string,LuaInterfaceBase,const std::string &>,boost::_bi::list2<boost::_bi::value<LuaInterfaceBase >,boost::arg<1>>> ] contrib\kaguya\include\kaguya/native_function.hpp(619): note: Siehe Verweis auf die Instanziierung der gerade kompilierten Klassen-template "kaguya::nativefunction::is_callable<boost::_bi::bind_t<std::string,boost::_mfi::mf1<std::string,LuaInterfaceBase,const std::string &>,boost::_bi::list2<boost::_bi::value,boost::arg<1>>>,void>". with [ T=LuaInterfaceBase ] src\lua\LuaInterfaceBase.cpp(65): note: Siehe Verweis auf die Instanziierung der gerade kompilierten Funktions-template "kaguya::FunctionInvokerType<std::tuple<boost::_bi::bind_t<std::string,boost::_mfi::mf1<std::string,LuaInterfaceBase,const std::string &>,boost::_bi::list2<boost::_bi::value,boost::arg<1>>>>> kaguya::function<boost::_bi::bind_t<std::string,boost::_mfi::mf1<std::string,LuaInterfaceBase,const std::string &>,boost::_bi::list2<boost::_bi::value,boost::arg<1>>>>(boost::_bi::bind_t<std::string,boost::_mfi::mf1<std::string,LuaInterfaceBase,const std::string &>,boost::_bi::list2<boost::_bi::value,boost::arg<1>>>)". with [ T=LuaInterfaceBase ] contrib\kaguya\include\kaguya/native_function.hpp(70): error C2146: Syntaxfehler: Fehlendes ">" vor Bezeichner "type"

Boost.Phoenix

contrib\kaguya\include\kaguya/nativefunction.hpp(70): error C2027: Verwendung des undefinierten Typs "kaguya::util::FunctionSignature<T,void>" with [ T=boost::phoenix::actor<boost::proto::exprns::basic_expr<boost::phoenix::detail::tag::functioneval,boost::proto::argsns::list3<boost::proto::exprns_::basicexpr<boost::proto::tagns::tag::terminal,boost::proto::argsns_::term<boost::phoenix::detail::member_function_ptr<1,std::string,std::string (_thiscall LuaInterfaceBase::* )(const std::string &)>>,0>,boost::proto::exprns::basicexpr<boost::proto::tagns::tag::terminal,boost::proto::argsns::term<LuaInterfaceBase *>,0>,boost::phoenix::actor<boost::proto::exprns::basicexpr<boost::proto::tagns::tag::terminal,boost::proto::argsns_::term<boost::phoenix::argument<1>>,0>>>,3>> ] contrib\kaguya\include\kaguya/nativefunction.hpp(70): note: Siehe Deklaration von "kaguya::util::FunctionSignature<T,void>" with [ T=boost::phoenix::actor<boost::proto::exprns::basic_expr<boost::phoenix::detail::tag::functioneval,boost::proto::argsns::list3<boost::proto::exprns_::basicexpr<boost::proto::tagns::tag::terminal,boost::proto::argsns_::term<boost::phoenix::detail::member_function_ptr<1,std::string,std::string (thiscall LuaInterfaceBase:: )(const std::string &)>>,0>,boost::proto::exprns_::basicexpr<boost::proto::tagns::tag::terminal,boost::proto::argsns_::term<LuaInterfaceBase >,0>,boost::phoenix::actor<boost::proto::exprns_::basicexpr<boost::proto::tagns::tag::terminal,boost::proto::argsns_::term<boost::phoenix::argument<1>>,0>>>,3>> ] contrib\kaguya\include\kaguya/native_function.hpp(619): note: Siehe Verweis auf die Instanziierung der gerade kompilierten Klassen-template "kaguya::nativefunction::iscallable<boost::phoenix::actor<boost::proto::exprns::basic_expr<Tag,Args,3>>,void>". with [ Tag=boost::phoenix::detail::tag::functioneval, Args=boost::proto::argsns::list3<boost::proto::exprns_::basicexpr<boost::proto::tagns::tag::terminal,boost::proto::argsns_::term<boost::phoenix::detail::member_function_ptr<1,std::string,std::string (thiscall LuaInterfaceBase:: )(const std::string &)>>,0>,boost::proto::exprns_::basicexpr<boost::proto::tagns::tag::terminal,boost::proto::argsns_::term<LuaInterfaceBase >,0>,boost::phoenix::actor<boost::proto::exprns_::basicexpr<boost::proto::tagns::tag::terminal,boost::proto::argsns::term<boost::phoenix::argument<1>>,0>>> ] src\lua\LuaInterfaceBase.cpp(66): note: Siehe Verweis auf die Instanziierung der gerade kompilierten Funktions-template "kaguya::FunctionInvokerType<std::tuple<boost::phoenix::actor<boost::proto::exprns::basicexpr<Tag,Args,3>>>> kaguya::function<boost::phoenix::actor<boost::proto::exprns::basic_expr<Tag,Args,3>>>(T)". with [ Tag=boost::phoenix::detail::tag::functioneval, Args=boost::proto::argsns::list3<boost::proto::exprns_::basicexpr<boost::proto::tagns::tag::terminal,boost::proto::argsns_::term<boost::phoenix::detail::member_function_ptr<1,std::string,std::string (thiscall LuaInterfaceBase:: )(const std::string &)>>,0>,boost::proto::exprns_::basicexpr<boost::proto::tagns::tag::terminal,boost::proto::argsns_::term<LuaInterfaceBase >,0>,boost::phoenix::actor<boost::proto::exprns_::basicexpr<boost::proto::tagns::tag::terminal,boost::proto::argsns::term<boost::phoenix::argument<1>>,0>>>, T=boost::phoenix::actor<boost::proto::exprns::basic_expr<boost::phoenix::detail::tag::functioneval,boost::proto::argsns::list3<boost::proto::exprns_::basicexpr<boost::proto::tagns::tag::terminal,boost::proto::argsns_::term<boost::phoenix::detail::member_function_ptr<1,std::string,std::string (thiscall LuaInterfaceBase:: )(const std::string &)>>,0>,boost::proto::exprns_::basicexpr<boost::proto::tagns::tag::terminal,boost::proto::argsns_::term<LuaInterfaceBase >,0>,boost::phoenix::actor<boost::proto::exprns_::basicexpr<boost::proto::tagns::tag::terminal,boost::proto::argsns_::term<boost::phoenix::argument<1>>,0>>>,3>> ] contrib\kaguya\include\kaguya/native_function.hpp(70): error C2146: Syntaxfehler: Fehlendes ">" vor Bezeichner "type"

OvermindDL1 commented 6 years ago

That seems odd. Boost.Bind and Boost.Phoenix just create bog-standard Function Objects (just like the C++11+ std::function supports). Does kaguya's function wrapper not support that? If not it should switch to boost::function (which can be embedded and re-name-spaced via one of the boost tools).

Flamefire commented 6 years ago

Was thinking the same, but there seems to be some more magic going on. However there is an undocumented template version of kaguya::function that takes the function signature as its first template param. Using this works.

OvermindDL1 commented 6 years ago

param. Using this works.

Ahh, that makes sense then, function object's can have multiple overrides in the same object so it could not distinguish otherwise without an argument unifying it, which a template argument would do (which is why both boost::function and std::function require it in all cases).

Flamefire commented 6 years ago

Ah ok. Then this is a documentation issue.