4

我正在尝试从与 Luabind 绑定的方法返回 std::shared_ptr,但它似乎无法识别该类型。

Luabind 代码:

module(lua)
[
    class_<Character, BaseEntity, std::shared_ptr<Character> > ("Character"),
        def("createCharacter", &Character::createCharacter)
];

创建字符代码:

std::shared_ptr<Character> Character::createCharacter(Game* gameInstance, const Character::CharacterSetup& characterSetup, string sprite, b2World* world)
{
    return std::shared_ptr<Character>(new Character(gameInstance, characterSetup, sprite, world));
}

如果我在 Lua 脚本中调用此方法,则不会返回任何内容,并且执行会停在那里。但是,如果我将方法更改为返回 Character*,它会按预期工作。一些谷歌搜索告诉我返回 shared_ptr 应该不是问题。

我究竟做错了什么?

另外,我有这段代码,所以 Luabind 可以理解 std::shared_ptr:

namespace luabind
{
    template <typename T>
    T* get_pointer(std::shared_ptr<T> const& p)
    {
        return p.get();
    }
}
4

1 回答 1

5

我必须解决同样的问题。

这有点复杂。基本上你需要用原型定义一个函数

template <typename T>
T* get_pointer(std::shared_ptr<T> const&);

此函数还必须与 相同的命名空间std::shared_ptr,因此std::。请注意,您的全局命名空间或命名空间中的函数将不起作用luabind因为luabind 使用特殊技巧来确保在检查某个类型是否为智能指针时仅使用 ADL。避免这种情况的唯一方法是在luabind::detail::has_get_pointer_命名空间中定义您的函数,而不仅仅是luabind.

但是单独在这个命名空间中定义你的函数也不起作用(至少对于 Boost <1.53)。尽管stdC++ 标准技术上不允许在命名空间中定义函数,但这是 Boost <1.53 的唯一可能方式。然而,从 1.53 开始,Boost为(and )定义了它自己的boost::get_pointer()重载。对于这个版本,让 Boost在命名空间中可见就足够了,因为 luabind 在任何使用智能指针的地方都是这个函数(参见标题)。那时甚至无法定义函数,因为 luabind 会引发模棱两可的调用。std::shared_ptrstd::unique_ptrget_pointer()luabind::detail::has_get_pointer_usingluabind/get_pointer.hppstd

因此,如果您想要一个适用于 Boost <1.53 和 >= 1.53 以及 MSVC 10(也许是 9)(这些定义在而不是)的get_pointer()重载,我可以为您提供我的(历史上成长的 ;-))标题:std::shared_ptrshared_ptrstd::tr1std

#ifndef SHAREDPTR_CONVERTER_HPP_INCLUDED
#define SHAREDPTR_CONVERTER_HPP_INCLUDED SHAREDPTR_CONVERTER_HPP_INCLUDED

#include <boost/version.hpp>

#if BOOST_VERSION >= 105300

#include <boost/get_pointer.hpp>


namespace luabind { namespace detail { namespace has_get_pointer_ {
    template<class T>
    T * get_pointer(std::shared_ptr<T> const& p) { return p.get(); }
}}}

#else // if BOOST_VERSION < 105300

#include <memory>

// Not standard conforming: add function to ::std(::tr1)
namespace std {

#if defined(_MSC_VER) && _MSC_VER < 1700
namespace tr1 {
#endif

    template<class T>
    T * get_pointer(shared_ptr<T> const& p) { return p.get(); }

#if defined(_MSC_VER) && _MSC_VER < 1700
} // namespace tr1
#endif

} // namespace std

#endif // if BOOST_VERSION < 105300

#endif
于 2013-03-04T17:50:04.497 回答