Question

J'ai un code pour l'interface Python pour C ++ qui fonctionne très bien, mais chaque fois que je regarde, je pense qu'il doit y avoir une meilleure façon de le faire. Sur le C ++ côté, il y a un type « variante » qui peut faire face à une gamme fixe de types de base - int, réel, chaîne, vecteur de variantes, etc. J'ai un code en utilisant l'API Python pour convertir des équivalents types Python. Il ressemble à ceci:

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

Le problème est la enchaînée si-else ifs. Il semble appeler pour une instruction switch, ou une table ou d'une carte des fonctions de création qui est calée par un identificateur de type. Autrement dit, je veux être capable d'écrire quelque chose comme:

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

Sur la base d'un lait écrémé de l'API docs il n'a pas été évident que la meilleure façon est d'obtenir le « typeID » ici directement. Je vois que je peux faire quelque chose comme ceci:

  PyTypeObject* type = value->ob_type;

Cette apparence me met rapidement aux informations de type, mais quelle est la façon la plus propre à utiliser pour se rapporter à l'ensemble limité de types que je suis intéressé?

Était-ce utile?

La solution

D'une certaine façon, je pense que vous avez répondu à votre question.

Quelque part, vous allez devoir choisir la fonctionnalité en fonction des données. La façon de le faire en C est d'utiliser des pointeurs de fonction.

Créer une carte de cartographes fonction object_type-> ... où chaque fonction a une interface clairement définie.

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

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

function_map.add(PyBool, PyBoolToVariant);

Maintenant, votre makeVariant peut ressembler à ceci.

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

Le plus dur va être obtenir le droit de la syntaxe de l'objet Carte. De plus, je suppose qu'il est un objet carte, vous pouvez utiliser qui prend des paramètres de type (<PyTypeObject*, variant*(PyObject*)).

J'ai probablement pas tout à fait obtenu la syntaxe correcte pour le second type de la carte. Il devrait être un pointeur vers une fonction qui prend un pointeur et renvoie un pointeur sur une variante.

J'espère que cela est utile.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top