ThePhD / sol2

Sol3 (sol2 v3.0) - a C++ <-> Lua API wrapper with advanced features and top notch performance - is here, and it's great! Documentation:
http://sol2.rtfd.io/
MIT License
4.12k stars 500 forks source link

Upcasting of unique_usertype fails in a signature matching #1442

Open niello opened 1 year ago

niello commented 1 year ago

I use unique_usertype_traits for a custom intrusive pointer Ptr.

template <typename T>
struct unique_usertype_traits<Ptr<T>>
{
    typedef T type;
    typedef Ptr<T> actual_type;
    static constexpr bool value = true;
    static bool is_null(const actual_type& ptr) { return !ptr; }
    static type* get(const actual_type& ptr) { return ptr.Get(); }
};

Then I bind a couple of functions, one to create a subclass of particular type and another to release it:

class Base {};
class SubclassA : public Base {};

class Factory
{
template<typename T> Ptr<T> Create() { return Ptr(new T()); }
void Release(Ptr<Base> p) { ... }
}

_Session->GetScriptState().new_usertype<Factory>("Factory"
    , "CreateSubclassA", &Factory::Create<SubclassA>
    , "Release", &Factory::Release
);

Then in Lua I do:

local x = MyFactory.CreateSubclassA()
MyFactory.Release(x)

and the call to Release fails. But if I change the binding to

    , "Release", [](Factory& self, Base* p) { self.Release(Ptr(p)); }

then everything works.

It seems that sol can't treat Ptr<Derived> as Ptr<Base> in an argument of a signature, although it can match Ptr<Derived> and Base*. Could you please fix this and enable direct binding in this case?