3

My code is:

template<class T>
static shared_ptr<T>& getSharedPtr(lua_State* L, int32_t arg)
{
    return *static_cast<shared_ptr<T>*>(lua_touserdata(L, arg));
}

This method returns a reference to a shared_ptr, so the actual reference counter decreases when the following function goes out of scope:

int32_t luaADelete(lua_State* L) {
    auto& a = getSharedPtr<A>(L, 1); // No increase ref count
    if (a) {
        a.reset(); // Real shared_ptr decrease ref count
    }

    return 0;
}

Everything works great, however I got to a point where I want to be able to return nullptr if the object on the stack is not a valid userdata, then the dilemma is that I cannot return nullptr in this case for the specific method, due to that it will always want to return a reference. static shared_ptr<T>& getSharedPtr(lua_State* L, int32_t arg)

The following method works, but it looks very ugly and I don't know if it is the right thing to do:

template<class T>
static shared_ptr<T>& getSharedPtr(lua_State* L, int32_t arg)
{
    if (!is<T>(L, arg)) {
        static shared_ptr<T> shared_empty;
        return shared_empty;
    }

    return *static_cast<shared_ptr<T>*>(lua_touserdata(L, arg));
}

I know that this case can be handled by returning the real pointer directly, but I don't want it to work that way, since it is more cumbersome when writing:

// shared_ptr->get()->method(...); BAD!

// shared_ptr.get(); OK!
// shared_ptr->method(...); OK!

If anyone can help me, I would be very grateful, I have been searching the internet and I can not find anything similar, so I decided to resort to writing this question here, thank you very much and have a good day!

Here is the example code that you can compile and test online to make it easier for you to help me: https://godbolt.org/z/of4cTMG5e

user438383
  • 5,716
  • 8
  • 28
  • 43
  • 1
    Fundamentally, you can’t return a reference to a `shared_ptr` that doesn’t actually exist. You can either wrap a reference in a class to put it in a `std::optional`, or use your pointer idea, but there’s no good way to avoid extra syntax when there is an extra possibility (*i.e.*, of no `shared_ptr`). – Davis Herring Nov 07 '21 at 20:24

0 Answers0