Пытаюсь экспортировать из С++ в Python перегруженную функцию, которая должна принимать, в том числе, None. Непонятно какой тип данных следует использовать в этом случае в качестве типа аргумента на стороне C++?
пример C++:
void foo_void() { std::cout<<__FUNCTION__ <<std::endl; }
void foo_str (std::string) { std::cout<<__FUNCTION__ <<std::endl; }
void foo_int (int ) { std::cout<<__FUNCTION__ <<std::endl; }
void foo_dbl (double ) { std::cout<<__FUNCTION__ <<std::endl; }
void foo_none(nullptr_t ) { std::cout<<__FUNCTION__ <<std::endl; } //< что использовать здесь вместо nullptr_t ?
using namespace boost::python;
BOOST_PYTHON_MODULE( test_variant )
{
def( "foo" , &foo_void );
def( "foo" , &foo_str );
def( "foo" , &foo_int );
def( "foo" , &foo_dbl );
def( "foo" , &foo_none );
}
python:
foo()
foo(1)
foo(1.0)
foo("Foo")
foo(None)
Выдает ошибку в последней сроке:
Traceback (most recent call last):
File "test.py", line 12, in <module>
foo(None)
Boost.Python.ArgumentError: Python argument types in
test_variant.foo(NoneType)
did not match C++ signature:
foo(std::nullptr_t)
foo(double)
foo(int)
foo(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)
foo(void)
Получилось реализовать перегрузку функции для типа None, введя дополнительный собственный тип, и зарегистрировав конвертер:
struct none_type
{
none_type() {}
none_type(const none_type&) {}
none_type(none_type&&) {}
none_type& operator = (const none_type&) { return *this; }
none_type& operator = (none_type&&) { return *this; }
bool operator == (const none_type&) const { return true; }
};
template<typename T>
struct convertible_from_Py_None
{
convertible_from_Py_None()
{
converter::registry::push_back(&convertible_from_Py_None::convertible,
&convertible_from_Py_None::construct,
type_id<T>());
}
static void* convertible(PyObject* obj_ptr)
{
return (Py_None==obj_ptr) ? obj_ptr : nullptr;
}
static void construct(PyObject* obj_ptr,
converter::rvalue_from_python_stage1_data* data)
{
assert(Py_None==obj_ptr);
typedef converter::rvalue_from_python_storage<T> storage_t;
storage_t* the_storage = reinterpret_cast<storage_t*>(data);
void* memory_chunk = the_storage->storage.bytes;
object obj(handle<>(borrowed(obj_ptr)));
T* output = new (memory_chunk) T();
// Use the contents of obj to populate output, e.g. using extract<>
data->convertible = memory_chunk;
}
};
Использование:
...
void foo_none(none_type) { std::cout<<__FUNCTION__ <<std::endl; }
...
BOOST_PYTHON_MODULE( test_variant )
{
convertible_from_Py_None<none_type>();
...
def( "foo" , &foo_none );
...
}
Продвижение своими сайтами как стратегия роста и независимости