cppyy с функцией std :: function - PullRequest
       22

cppyy с функцией std :: function

2 голосов
/ 23 апреля 2020

Я использую cppyy. Я хочу передать функцию на мой C ++. C ++ ожидает функцию подписи std::function<double(std::vector<double>)>. Я не знаю, как это сделать. Вот минимальный пример ошибки:

import cppyy

# To be passed to C
def callback(x):
  return 10.

cppyy.cppdef("double callback_vector(const std::function<double(std::vector<double>)>& callback, std::vector<double> x) { return callback(x); }")
cppyy.cppdef("double callback(const std::function<double(double)>& callback, std::vector<double> x) { return callback(x[0]); }")

cppyy.gbl.callback(callback, [1]) # works
cppyy.gbl.callback_vector(callback, [1]) # fails

, но я нахожу

Traceback (most recent call last):
  File "test.py", line 11, in <module>
    cppyy.gbl.callback_vector(callback, [1])
TypeError: double ::callback_vector(function<double(std::vector<double> >& callback, vector<double> x) =>
    TypeError: could not convert argument 1

Другими словами, с std::function<double(std::vector<double>)> он терпит неудачу, но с более простой подписью std::function<double(double)> работает.

1 Ответ

2 голосов
/ 23 апреля 2020

Как прокомментировано, проблема глубоко внутри бэкэнда (ошибка синтаксического анализа), которая превращает имя std::function в нечто неузнаваемое. Это делается для ряда обходных путей, которые я пробовал.

Наиболее близкое решение, которое я могу придумать, заключается в следующем:

cppyy.cppdef("""
    struct VecDArg : public std::vector<double> {
        VecDArg(const std::vector<double>& v) : std::vector<double>(v) {}
    };
    double wrap_callback_vector(const std::function<double(VecDArg)>& wrap, const std::vector<double>& x) {
        return callback_vector(wrap, x);
    }
""")

cppyy.gbl.callback_vector = cppyy.gbl.wrap_callback_vector
cppyy.gbl.callback_vector(callback, [1])

Причина, по которой вышеприведенное работает, заключается в том, что скрывает имя типа от бэкэнда и таким образом предотвращает проблему с анализом. Исходя из std::vector, класс Python в большинстве своем не мудрый.

EDIT : теперь исправлен в репо. Будет частью релиза 1.7.0. Спасибо за сообщение!

...