Проблемы с вызовом шаблонной функции C ++ из JavaScript в QT с QvariantC++

Программы на C++. Форум разработчиков
Ответить Пред. темаСлед. тема
Anonymous
 Проблемы с вызовом шаблонной функции C ++ из JavaScript в QT с Qvariant

Сообщение Anonymous »

Проблема
Я пытаюсь разоблачить шаблонные функции C ++ в JavaScript, используя QTE QWebengineView и QWebChannel . Цель состоит в том, чтобы включить динамический вызов функций C ++ из JavaScript, с различными типами аргументов и возвратными значениями.
Проблемы
Преобразование аргумента
Я использую рекурсивный шаблон (convert_args) для преобразования аргументов из Qvariantlist в типы C ++. Тем не менее, я не уверен, правильно ли этот подход обрабатывает ссылки и различные типы аргументов, особенно при работе со сложными или нетривиальными типами данных. > После преобразования аргументов в правильные типы я сталкиваюсь с проблемами с вызовом функции, используя std :: invoke . Типы, по -видимому, несоответствия или ссылки обрабатываются неправильно при распаковке аргументов из кортежа. и неполные типы во время компиляции. В частности, я сталкиваюсь с проблемами при вызове функции с аргументами, распакованными из std :: tuple из -за несовместимости типа.
Что я попробовал
использовал рекурсивный шаблон (convert_args) в преобразование QvariantList в std :: tuple с ожидаемыми типами аргументов.
anpilized std :: invoke для вызова шаблонной функции C ++, передавая функцию. Раскрытые аргументы из корпуса.
обработанные ссылки с использованием std :: remove_reference_t < /code> для учета ссылок на типы в аргументах.
Несмотря на это Попытки, проблема сохраняется. Функция должна выполняться правильно с соответствующими типами аргументов и возвращать ожидаемое значение. < /P>
#include
#include
#include
#include
#include
#include
#include

template
struct function_traits : function_traits {};

template
struct function_traits
{
using return_type = R;
using arg_types = std::tuple;
using signature_t = R(Args...);
static constexpr size_t arity = sizeof...(Args);

template
using arg = typename std::tuple_element::type;
};

template
struct function_traits
{
using return_type = R;
using arg_types = std::tuple;
using signature_t = R(Args...);
static constexpr size_t arity = sizeof...(Args);

template
using arg = typename std::tuple_element::type;
};

template
struct function_traits
{
using return_type = ReturnType;
using arg_types = std::tuple;
using signature_t = ReturnType(Args...);
static constexpr size_t arity = sizeof...(Args);

template
using arg = typename std::tuple_element::type;
};

template
struct function_traits
{
using return_type = ReturnType;
using arg_types = std::tuple;
using signature_t = ReturnType(Args...);
static constexpr size_t arity = sizeof...(Args);

template
using arg = typename std::tuple_element::type;
};

template
struct function_traits
{
using return_type = ReturnType;
using arg_types = std::tuple;
using signature_t = ReturnType(Args...);
static constexpr size_t arity = sizeof...(Args);

template
using arg = typename std::tuple_element::type;
};

template
struct function_traits
{
using return_type = ReturnType;
using arg_types = std::tuple;
using signature_t = ReturnType(Args...);
static constexpr size_t arity = sizeof...(Args);

template
using arg = typename std::tuple_element::type;
};

template
struct function_traits
{
using return_type = ReturnType;
using arg_types = std::tuple;
using signature_t = ReturnType(BoundArgs...);
static constexpr size_t arity = sizeof...(BoundArgs);

template
using arg = typename std::tuple_element::type;
};

template
using function_signature_t = typename function_traits::signature_t;

class Invoker : public QObject {
Q_OBJECT
public:
using callback_t = std::function;

explicit Invoker(QObject* parent = nullptr) : QObject(parent) {}

void add(const QString& name, const callback_t& callback) {
m_functions[name] = std::move(callback);
}

Q_INVOKABLE QVariant call(const QString& name, const QVariantList& args) {
return m_functions[name](std::move(args));
}

Q_INVOKABLE void debug(const QString& message) {
qDebug().noquote() resize(800, 600);

channel->registerObject("invoker", &invoker);
view->page()->setWebChannel(channel);

view->setUrl(QUrl::fromLocalFile(""));
}

MainWindow::~MainWindow() {
delete view;
delete channel;
}

template
T convert_variant(const QVariant& var) {
return var.value();
}

template
auto convert_args(const QVariantList& args) {
if constexpr (Index < sizeof...(ArgTypes)) {
return std::tuple_cat(
std::make_tuple(convert_variant(args.at(Index))),
convert_args(args)
);
} else {
return std::tuple{};
}
}

template
decltype(auto) call_function_impl(Function&& function, Tuple&& tuple, std::index_sequence) {

return std::invoke(std::forward(function),
std::forward(std::get(std::forward(tuple)))...);
}

template
decltype(auto) call_function(Function&& function, Tuple&& tuple) {
return call_function_impl(
std::forward(function),
std::forward(tuple),
std::make_index_sequence{}
);
}

template
void MainWindow::expose(const std::string& name, Function&& function) {
using argument_types = typename function_traits::arg_types;
using return_type = typename function_traits::return_type;

invoker.add(QString::fromStdString(name),
[function = std::forward(function)](const QVariantList& args) -> QVariant {
constexpr size_t arity = webflex::utils::function_traits::arity;

if (args.size() == arity) {

auto typed_args = convert_args(args);

return call_function(function, typed_args);
}

return QVariant();
});
}

void function(int, QString) {}

int main(int argc, char** argv) {
QApplication a(argc, argv);

MainWindow w;

w.expose("add", [](int x, int y) {
return x + y;
});

w.show();

return a.exec();
}

#include "main.moc"
< /code>
Сообщения об ошибках < /p>
ошибки компиляции, связанные с типами несоответствующих аргументов и неполными типами во время вызова функции. < /p>
`
In file included from /home/hacker-pro/Qt/6.7.3/gcc_64/include/QtCore/qtypeinfo.h:13,
from /home/hacker-pro/Qt/6.7.3/gcc_64/include/QtCore/qglobal.h:47,
from /home/hacker-pro/Qt/6.7.3/gcc_64/include/QtGui/qtguiglobal.h:7,
from /home/hacker-pro/Qt/6.7.3/gcc_64/include/QtWidgets/qtwidgetsglobal.h:7,
from /home/hacker-pro/Qt/6.7.3/gcc_64/include/QtWidgets/qmainwindow.h:7,
from /home/hacker-pro/Qt/6.7.3/gcc_64/include/QtWidgets/QMainWindow:1,
from /home/hacker-pro/Projects/TestPrfoject/main.cpp:1:
/usr/include/c++/13/tuple: In instantiation of ‘constexpr decltype(auto) std::__apply_impl(_Fn&&, _Tuple&&, index_sequence) [with _Fn = const main(int, char**)::&; _Tuple = tuple&; long unsigned int ..._Idx = {0}; index_sequence = integer_sequence]’:
/usr/include/c++/13/tuple:2299:31: required from ‘constexpr decltype(auto) std::apply(_Fn&&, _Tuple&&) [with _Fn = const main(int, char**)::&; _Tuple = tuple&]’
/home/hacker-pro/Projects/TestPrfoject/main.cpp:93:22: required from ‘decltype(auto) call_function_impl(Function&&, Tuple&&, std::index_sequence) [with Function = const main(int, char**)::&; Tuple = std::tuple&; long unsigned int ...I = {0}; std::index_sequence = std::integer_sequence]’
/home/hacker-pro/Projects/TestPrfoject/main.cpp:98:30: required from ‘decltype(auto) call_function(Function&&, Tuple&&) [with Function = const main(int, char**)::&; Tuple = std::tuple&]’
/home/hacker-pro/Projects/TestPrfoject/main.cpp:123:29: required from ‘void MainWindow::expose(const std::string&, Function&&) [with Function = main(int, char**)::; std::string = std::__cxx11::basic_string]’
/home/hacker-pro/Projects/TestPrfoject/main.cpp:135:13: required from here
/usr/include/c++/13/tuple:2288:27: error: no matching function for call to ‘__invoke(const main(int, char**)::&, std::__tuple_element_t&)’
2288 | return std::__invoke(std::forward(__f),
| ~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
2289 | std::get(std::forward(__t))...);
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/13/variant:41,
from /home/hacker-pro/Qt/6.7.3/gcc_64/include/QtCore/qtypeinfo.h:11:
/usr/include/c++/13/bits/invoke.h:90:5: note: candidate: ‘template constexpr typename std::__invoke_result::type std::__invoke(_Callable&&, _Args&& ...)’
90 | __invoke(_Callable&& __fn, _Args&&... __args)
| ^~~~~~~~
/usr/include/c++/13/bits/invoke.h:90:5: note: template argument deduction/substitution failed:
/usr/include/c++/13/bits/invoke.h: In substitution of ‘template constexpr typename std::__invoke_result::type std::__invoke(_Callable&&, _Args&& ...) [with _Callable = const main(int, char**)::&; _Args = {std::tuple&}]’:
/usr/include/c++/13/tuple:2288:27: required from ‘constexpr decltype(auto) std::__apply_impl(_Fn&&, _Tuple&&, index_sequence) [with _Fn = const main(int, char**)::&; _Tuple = tuple&; long unsigned int ..._Idx = {0}; index_sequence = integer_sequence]’
/usr/include/c++/13/tuple:2299:31: required from ‘constexpr decltype(auto) std::apply(_Fn&&, _Tuple&&) [with _Fn = const main(int, char**)::&; _Tuple = tuple&]’
/home/hacker-pro/Projects/TestPrfoject/main.cpp:93:22: required from ‘decltype(auto) call_function_impl(Function&&, Tuple&&, std::index_sequence) [with Function = const main(int, char**)::&; Tuple = std::tuple&; long unsigned int ...I = {0}; std::index_sequence = std::integer_sequence]’
/home/hacker-pro/Projects/TestPrfoject/main.cpp:98:30: required from ‘decltype(auto) call_function(Function&&, Tuple&&) [with Function = const main(int, char**)::&; Tuple = std::tuple&]’
/home/hacker-pro/Projects/TestPrfoject/main.cpp:123:29: required from ‘void MainWindow::expose(const std::string&, Function&&) [with Function = main(int, char**)::; std::string = std::__cxx11::basic_string]’
/home/hacker-pro/Projects/TestPrfoject/main.cpp:135:13: required from here
/usr/include/c++/13/bits/invoke.h:90:5: error: no type named ‘type’ in ‘struct std::__invoke_result’
make[2]: *** [CMakeFiles/main.dir/build.make:93: CMakeFiles/main.dir/main.cpp.o] Ошибка 1
make[1]: *** [CMakeFiles/Makefile2:110: CMakeFiles/main.dir/all] Ошибка 2
make: *** [Makefile:136: all] Ошибка 2
`


Подробнее здесь: https://stackoverflow.com/questions/794 ... h-qvariant
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • Как я могу преобразовать QVariant в QString и наоборот в Qt?
    Anonymous » » в форуме C++
    0 Ответы
    21 Просмотры
    Последнее сообщение Anonymous
  • QVariant сравнение с собственными типами работает?
    Anonymous » » в форуме C++
    0 Ответы
    9 Просмотры
    Последнее сообщение Anonymous
  • Qvariant с std :: shared_ptr
    Anonymous » » в форуме C++
    0 Ответы
    8 Просмотры
    Последнее сообщение Anonymous
  • Использование псевдонимов для шаблонной функции-члена
    Гость » » в форуме C++
    0 Ответы
    20 Просмотры
    Последнее сообщение Гость
  • C ++ разветвление времени компиляции (как переключатель типа) в определении шаблонной функции
    Anonymous » » в форуме C++
    0 Ответы
    8 Просмотры
    Последнее сообщение Anonymous

Вернуться в «C++»