У меня есть некоторый код к интерфейсу Python к C++, который хорошо работает, но каждый раз я смотрю на него, я думаю, что должен быть лучший способ сделать это. На стороне C++ существует 'различный' тип, который может иметь дело с фиксированным диапазоном основных типов - интервал, реальный, строка, вектор вариантов, и т.д. У меня есть некоторый код с помощью API Python для преобразования из эквивалентных типов Python. Это выглядит примерно так:
variant makeVariant(PyObject* value)
{
if (PyString_Check(value)) {
return PyString_AsString(value);
}
else if (value == Py_None) {
return variant();
}
else if (PyBool_Check(value)) {
return value == Py_True;
}
else if (PyInt_Check(value)) {
return PyInt_AsLong(value);
}
else if (PyFloat_Check(value)) {
return PyFloat_AsDouble(value);
}
// ... etc
Проблемой является цепочечное если еще IFS. Это, кажется, вызывает для оператора переключения, или таблицы или карты функций создания, которая включается идентификатором типа. Другими словами, я хочу смочь записать что-то как:
return createFunMap[typeID(value)](value);
На основе просматривания документов API не было очевидно, что лучший способ состоит в том, чтобы получить 'идентификатор типа' здесь непосредственно. Я вижу, что могу сделать что-то вроде этого:
PyTypeObject* type = value->ob_type;
Это, по-видимому, получает меня быстро к информации о типе, но что самый чистый путь состоит в том, чтобы использовать это для касаний ограниченного набора типов, которыми я интересуюсь?
В некотором смысле, я думаю, вы ответили на свой вопрос.
Где-то вам придется выбирать функции на основе данных. В C это можно сделать с помощью указателей на функции.
Создайте карту сопоставителей object_type-> function ... где каждая функция имеет четко определенный интерфейс.
variant PyBoolToVariant(PyObject *value) {
return value == Py_True;
}
Map<PyTypeObject*,variant* (PyObject*)> function_map;
function_map.add(PyBool, PyBoolToVariant);
Теперь ваш makeVariant может выглядеть так.
variant makeVariant(PyObject *value) {
return (*function_map.get(value->ob_type))(value);
}
Сложнее всего будет получить правильный синтаксис для объекта Map. Кроме того, я предполагаю, что вы можете использовать объект Map, который принимает параметры типа (
Я, вероятно, не совсем понял синтаксис второго типа карты. Это должен быть указатель на функцию, которая принимает один указатель и возвращает указатель на вариант.
Надеюсь, это полезно.