Вопрос

У меня есть какой-то код для интерфейса Python к C ++, который работает нормально, но каждый раз, когда я смотрю на него, я думаю, что должен быть лучший способ сделать это. На стороне C ++ есть тип «вариант», который может иметь дело с фиксированным диапазоном основных типов - int, Real, String, Vector Variants и т. Д. У меня есть какой-то код, используя Python API для преобразования из эквивалентных типов 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 Mappers ... где каждая функция имеет четко определенный интерфейс.

variant PyBoolToVariant(PyObject *value) {
    return value == Py_True;
}

Map<PyTypeObject*,variant* (PyObject*)> function_map;

function_map.add(PyBool, PyBoolToVariant);

Теперь ваш макиавариант может выглядеть так.

variant makeVariant(PyObject *value) {
    return (*function_map.get(value->ob_type))(value);
}

Тяжелая часть собирается получить синтаксис прямо для объекта карты. Кроме того, я предполагаю, что существует объект карты, который вы можете использовать, который принимает параметры типа (<PyTypeObject*, variant*(PyObject*)).

Я, вероятно, не совсем получил синтаксис правильной для второго типа карты. Это должно быть указателем на функцию, которая принимает один указатель и возвращает указатель на вариант.

Я надеюсь, что это полезно.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top