7

我有一些代码可以将 Python 与 C++ 接口,这些代码运行良好,但每次我看到它时,我都认为必须有更好的方法来做到这一点。在 C++ 方面,有一个“变体”类型可以处理固定范围的基本类型——int、real、string、变体向量等。我有一些代码使用 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

问题是链式 if-else ifs。它似乎在调用一个 switch 语句,或者一个由类型标识符作为键的创建函数的表或映射。换句话说,我希望能够写出类似的东西:

  return createFunMap[typeID(value)](value);

根据对 API 文档的浏览,直接在此处获取“typeID”的最佳方法并不明显。我看到我可以做这样的事情:

  PyTypeObject* type = value->ob_type;

这显然让我快速了解类型信息,但是使用它与我感兴趣的有限类型集相关的最简洁的方法是什么?

4

1 回答 1

3

在某种程度上,我认为你已经回答了你自己的问题。

在某个地方,您将不得不根据数据选择功能。在 C 中做到这一点的方法是使用函数指针。

创建一个 object_type->function mappers... 其中每个函数都有一个明确定义的接口。

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 对象获取正确的语法。另外,我假设您可以使用一个带有类型参数 ( <PyTypeObject*, variant*(PyObject*)) 的 Map 对象。

对于第二种类型的 Map,我可能还没有完全正确的语法。它应该是一个指向函数的指针,该函数接受一个指针并返回一个指向变体的指针。

我希望这是有帮助的。

于 2010-06-22T12:26:18.233 回答