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

时间:2015-10-08 14:48:39

标签: python c++ templates boost

所以这个问题与我选择的解决我真实问题的方法有关,为了给出尽可能多的图片,这个问题就是:基本上我有一个带有很多模板参数的函数我就是这样的试图暴露给Python。与使用宏来做一些噩梦以消除我需要的所有模板参数组合相反,我已经使用boost::python::object进行类型擦除,然后使用extract来获取类型I需要它。

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

#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获得一个非常数左值,但我不知道如何做到这一点。

思想?

1 个答案:

答案 0 :(得分:2)

当你这样做时:

boost::python::extract<Dog> 

您正在找回Dog。如果您想再获得左值引用,则需要构造相应的extract对象:

boost::python::extract<Dog&>

当然,更多的Python解决方案就是留在python领域。类似的东西:

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