C ++ отлично декодирует указатель на пустоту для Matlab mex - PullRequest
3 голосов
/ 19 сентября 2011

Я пытаюсь написать мекс-функцию C ++ для Matlab, которая может обрабатывать несколько типов данных. Matlab дает мне mxArray*, из которого я могу получить void* для данных, и mxClassID, сообщая мне тип данных. Так что я могу сделать что-то вроде:

void *data = mxGetData(mxarray);
switch (mxGetClassID(mxarray)) {
  case mxDOUBLE_CLASS:
    my_function(static_cast<double *>(data));
  ...

my_function является шаблоном, поэтому он хорошо обрабатывает разные типы данных. Но все равно очень раздражает необходимость иметь этот переключатель для всех возможных my_function1, my_function2 и т. Д.

Пока что решение, которое я нашел, заключается в использовании функционального подхода и метода, который принимает функтор:

template <typename ReturnType, typename FunctorType>
ReturnType mxarr_apply(const mxArray *inarr, FunctorType functor) {
  void *data = mxGetData(inarr);
  switch (mxGetClassID(inarr)) {
    case mxDOUBLE_CLASS:
      return (ReturnType) functor(static_cast<double *>(data));
    ...

Таким образом, я могу поместить свою логику в функтор (с шаблоном operator()), и мне не нужно будет снова и снова переключаться.

Но мне интересно, есть ли другой способ? В Java я думаю, что у меня может быть просто функция, которая преобразует mxClassID непосредственно в class ссылку, которая затем может быть использована для гибкого создания экземпляра типа во время выполнения, но, похоже, это не вариант в C ++.

Ответы [ 2 ]

2 голосов
/ 19 сентября 2011

Ты прав. В C ++ нет способа получить ссылку на класс во время выполнения. Вы должны написать переключатель, по крайней мере, один раз.

0 голосов
/ 19 сентября 2011

Если вы сталкиваетесь с необходимостью написания нескольких ключей, вы можете захотеть скрыть их логику в фабрике, которая вернула бы правильный функтор, учитывая тип

void *data = mxGetData(mxarray);
functor func = FunctorFactory::Get(mxGetClassID(mxarray));
func (reinterpret_cast<double*>(data));

или просто создайте карту (желательно неупорядоченную или хэш) типов для функторов.

void *data = mxGetData(mxarray);
functor func = functorMap[mxGetClassID(mxarray)]; // need to check for key availability
func (reinterpret_cast<double*>(data));
...