Я пытаюсь вернуть std :: shared_ptr из метода, связанного с Luabind, но, похоже, он не распознает тип.
Код Luabind:
module(lua)
[
class_<Character, BaseEntity, std::shared_ptr<Character> > ("Character"),
def("createCharacter", &Character::createCharacter)
];
код 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 *, он будет работать как положено. Некоторый поиск в Google говорит мне, что возвращение shared_ptr не должно быть проблемой.
Что я делаю неправильно?
Кроме того, у меня есть этот код, чтобы Luabind мог понимать std :: shared_ptr:
namespace luabind
{
template <typename T>
T* get_pointer(std::shared_ptr<T> const& p)
{
return p.get();
}
}
Мне пришлось решить ту же проблему.
Это немного сложно. В основном вам нужно определить функцию с прототипом
template <typename T>
T* get_pointer(std::shared_ptr<T> const&);
Эта функция дополнительно должна находиться в том же пространстве имен, что и std::shared_ptr
таким образом std::
, Обратите внимание, что функция в глобальное пространство имен или luabind
Пространство имен, как твой, не будет работать, потому что Луабинд использует специальные трюки чтобы убедиться, что только ADL используется при проверке, является ли определенный тип умным указателем. Единственный способ обойти это — определить вашу функцию в luabind::detail::has_get_pointer_
пространство имен вместо просто luabind
,
Но определение вашей функции только в этом пространстве имен тоже не сработает (по крайней мере, для Boost <1,53). Хотя определение функции в пространстве имен std
технически не допускается стандартом C ++, это единственный возможный способ для Boost <1,53. Начиная с 1.53, однако, Boost определяет свой собственный boost::get_pointer()
перегрузки для std::shared_ptr
(а также std::unique_ptr
). Для этой версии достаточно сделать Boost’s get_pointer()
видимый в luabind::detail::has_get_pointer_
пространство имен, так как Luabind using
эта функция везде, где она использует умные указатели (см. luabind/get_pointer.hpp
заголовок). Определение функции в std
тогда даже не будет работать, потому что luabind вызовет неоднозначный вызов.
Так что если вы хотите get_pointer()
перегрузка для std::shared_ptr
который работает для Boost <1,53 и> = 1,53, а также для MSVC 10 (и, возможно, 9) (они определяют shared_ptr
в std::tr1
вместо std
), Я могу предложить вам мой (исторически выросший ;-)) заголовок:
#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
Других решений пока нет …