【问题标题】:error C2027: use of undefined type 'boost::python::detail::reference_existing_object_requires_a_pointer_or_reference_return_type<R>'错误 C2027:使用未定义类型 'boost::python::detail::reference_existing_object_requires_a_pointer_or_reference_return_type<R>'
【发布时间】:2015-11-17 21:06:12
【问题描述】:

我收到错误reference_existing_object_requires_a_pointer_or_reference_return_type。

这是代码。

boost::shared_ptr<CDB::Basic> GetCdbWrapper(boost::shared_ptr<A> cmd)
    {
        return cmd->Cdb();
    }
}

virtual boost::shared_ptr<CDB::Basic> Cdb() { 
    boost::shared_ptr<CDB::Basic> CdbObj;
    return CdbObj;
}
boost::shared_ptr<CDB::Basic> GetCdb() { 
    return this->Cdb(); 
}


class_<A, bases<Core::CommandBase>, boost::shared_ptr<A>, boost::noncopyable, >("A",
    ":description:\n",
    boost::python::no_init
)

.def("Cdb", &A::GetCdb,
    ":description:\n",
    return_value_policy<reference_existing_object>()
);

我可以知道上面的代码有什么问题吗?我得到如下编译错误。

error C2027: use of undefined type 'boost::python::detail::reference_existing_object_requires_a_pointer_or_reference_return_type<R>'
1>        with
1>        [
1>            R=result_t
1>        ]
1>        c:\boost\boost_1_47_0\boost\python\detail\caller.hpp(200) : while compiling class template member function 'PyObject *boost::python::detail::caller_arity<1>::impl<F,Policies,Sig>::operator ()(PyObject *,PyObject *)'
1>        with
1>        [
1>            F=boost::shared_ptr<CDB::Basic> (__thiscall A::* )(void),
1>            Policies=boost::python::return_value_policy<boost::python::reference_existing_object>,
1>            Sig=boost::mpl::vector2<boost::shared_ptr<CDB::Basic>, A &>
1>        ]

【问题讨论】:

  • 据我所知(在没有进一步了解 boost 实现的情况下)reference_existing_object 策略要求返回的对象是指针或引用类型。 shared_ptr 既不是指针也不是引用,而是类类型,它在代码中按值返回。尽管shared_ptr 是一个资源管理指针包装类,但它本身并不是一个指针。我认为使用智能指针时不需要reference_existing_object
  • 谢谢。删除 return_value_policy() 解决了这个问题。

标签: c++ c++11 boost shared-ptr boost-python


【解决方案1】:

return_internal_reference 文档中所述,返回的对象通过指针或引用引用现有的内部对象:

return_internal_reference [...] 允许安全地返回指向内部保存的对象的指针和引用 [...] 而无需复制所指对象。

Boost.Python 提供了一些概念检查,并且通常类型会突出失败的概念。在这种特殊情况下,编译器错误有:

reference_existing_object_requires_a_pointer_or_reference_return_type

这是因为GetCdb()函数按值返回boost::shared_ptr&lt;CDB::Basic&gt;,不符合return_internal_reference调用策略的要求。要解决此问题,请使用按值返回副本的默认调用策略。这要求 CDB::Basic 通过 Boost.Python 公开为由 boost::shared_ptr 持有。总体而言,这种行为与shared_ptr 经常使用的行为没有太大区别,后者创建shared_ptr 的副本以保持共享所有权。


这是demonstrating此行为的示例:

#include <boost/python.hpp>

// Mocks...
class spam {};

boost::shared_ptr<spam> get_spam()
{
  boost::shared_ptr<spam> spam_ptr(new spam());
  return spam_ptr;
}

BOOST_PYTHON_MODULE(example)
{
  namespace python = boost::python;
  python::class_<spam, boost::shared_ptr<spam>, boost::noncopyable>(
      "Spam", python::no_init);
  python::def("get_spam", &get_spam);
}

互动使用:

>>> import example
>>> spam = example.get_spam()
>>> assert(type(spam) is example.Spam)

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-04
相关资源
最近更新 更多