将boost::python::object转换为(非const)左值

Converting boost::python::object to (non-const) lvalue

本文关键字:const 左值 转换 boost python object      更新时间:2023-10-16

所以这个问题是关于我选择的解决方案来解决我的实际问题,为了尽可能完整地给出一个图片,它是这样的:基本上,我有一个函数,有很多模板参数,我试图向Python公开。与使用宏来消除我需要的所有模板参数组合的噩梦相反,我一直使用boost::python::object进行类型擦除,然后使用extract从中获取我需要的类型。

然而,似乎不可能从boost::python::extract中获得非const左值。这里有一个玩具问题:

#include<iostream>
#include<boost/python.hpp>
class Dog
{
public:
   void noise() { std::cout << "WOOF" << std::endl; }
};
class Cat
{
public:
   void noise() { std::cout << "MEOW" << std::endl; }
};
template< class Animal >
void make_noise(Animal & a)
   { a.noise(); }
//Wrapping for boost python
void make_noise_py(boost::python::object & a)
{
   {
      boost::python::extract<Dog> get(a);
      if(get.check())
      {
         Dog & d = get();
         make_noise(d);
      }
   }
   {
      boost::python::extract<Cat> get(a);
      if(get.check())
      {
         Cat & c = get();
         make_noise(c);
      }
   }
}
BOOST_PYTHON_MODULE(main)
{
   boost::python::def("make_noise", make_noise_py);
}

请注意,虽然这个问题只有一个模板参数和两个选项,我的实际问题有大约4个模板参数,通常有两个以上的选项为每个…因此,冲压每个模板是不可能的,使用宏似乎更加混乱。我能看到的唯一其他选择是使用const_cast,如果可以的话,我也喜欢避免使用它。我真的很想从boost::python::object中得到一个非const左值,但我不知道如何做到这一点。

想法吗?

当你这样做的时候:

boost::python::extract<Dog> 

你会得到一个Dog。如果希望返回左值引用,则需要构造相应的extract对象:

boost::python::extract<Dog&>

当然,更Python的解决方案是留在Python领域。比如:

void make_noise(boost::python::object o) {
    o.attr("noise")();
}