QHttpServer: use function pointer as ViewHandler
-
Using Qt 6.4.3, playing with QHttpServer.
Documentation: ViewHandler can be a function pointer, non-mutable lambda...
But I don't know how to use it with a function pointer:
#include <QCoreApplication> #include <QHttpServer> const char * responseFunction() { return "Hello world!"; } int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); QHttpServer server; //server.route("/", [](){ return "Hello world!";}); // this compiles server.route("/", &responseFunction); // this doesn't compile server.listen(QHostAddress::Any, 2222); return a.exec(); }
The program compiles and works when lambda is used. But I can't compile it with a function pointer. What am I doing wrong?
-
And fixed
-
@Tarae said in QHttpServer: use function pointer as ViewHandler:
server.route("/", &responseFunction); // this doesn't compile
Usually I thought it does not matter with C function pointers, but try removing that
&
. PlainresponseFunction
is a function pointer. Does that resolve?Having said that, I don't think your function is acceptable anyway:
ViewHandler can be a function pointer, non-mutable lambda, or any other copiable callable with const call operator. The callable can take two optional special arguments: const QHttpServerRequest& and QHttpServerResponder&&. These special arguments must be the last in the parameter list, but in any order, and there can be none, one, or both of them present.
Oh, no, I see, the parameters are optional anyway.
-
@jsulm Ok, here it is:
14:38:56: Running steps for project httptest... 14:38:56: Configuration unchanged, skipping qmake step. 14:38:56: Starting: "/usr/bin/make" -j8 /home/user/Qt/6.4.3/gcc_64/bin/qmake -o Makefile ../httptest/httptest.pro -spec linux-g++ CONFIG+=debug CONFIG+=qml_debug g++ -c -pipe -g -std=gnu++1z -Wall -Wextra -fPIC -D_REENTRANT -DQT_QML_DEBUG -DQT_HTTPSERVER_LIB -DQT_WEBSOCKETS_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB -I../httptest -I. -I/home/user/Qt/6.4.3/gcc_64/include -I/home/user/Qt/6.4.3/gcc_64/include/QtHttpServer -I/home/user/Qt/6.4.3/gcc_64/include/QtWebSockets -I/home/user/Qt/6.4.3/gcc_64/include/QtNetwork -I/home/user/Qt/6.4.3/gcc_64/include/QtCore -I. -I/home/user/Qt/6.4.3/gcc_64/mkspecs/linux-g++ -o main.o ../httptest/main.cpp In file included from /home/user/Qt/6.4.3/gcc_64/include/QtHttpServer/qhttpserverrouterviewtraits.h:8, from /home/user/Qt/6.4.3/gcc_64/include/QtHttpServer/qhttpserverrouter.h:8, from /home/user/Qt/6.4.3/gcc_64/include/QtHttpServer/qhttpserver.h:9, from /home/user/Qt/6.4.3/gcc_64/include/QtHttpServer/QHttpServer:1, from ../httptest/main.cpp:2: /home/user/Qt/6.4.3/gcc_64/include/QtHttpServer/qhttpserverviewtraits_impl.h: In instantiation of ‘struct QtPrivate::FunctionTraits<const char* (* const&)()>’: /home/user/Qt/6.4.3/gcc_64/include/QtHttpServer/qhttpserverviewtraits_impl.h:65:11: required from ‘struct QtPrivate::ViewTraits<const char* (* const&)(), false>’ /home/user/Qt/6.4.3/gcc_64/include/QtHttpServer/qhttpserverrouterviewtraits.h:18:8: required from ‘struct QtPrivate::RouterViewTraitsHelper<const char* (* const&)(), false>’ /home/user/Qt/6.4.3/gcc_64/include/QtHttpServer/qhttpserverrouterviewtraits.h:122:11: required from ‘struct QHttpServerRouterViewTraits<const char* (* const&)(), false>’ /home/user/Qt/6.4.3/gcc_64/include/QtHttpServer/qhttpserverrouter.h:57:39: required by substitution of ‘template<class ViewHandler, class ViewTraits> typename ViewTraits::BindableType QHttpServerRouter::bindCaptured(ViewHandler&&, const QRegularExpressionMatch&) const [with ViewHandler = const char* (* const&)(); ViewTraits = QHttpServerRouterViewTraits<const char* (* const&)(), false>]’ /home/user/Qt/6.4.3/gcc_64/include/QtHttpServer/qhttpserver.h:135:59: required from ‘bool QHttpServer::routeImpl(Args&& ..., ViewHandler&&) [with Rule = QHttpServerRouterRule; ViewHandler = const char* (*)(); ViewTraits = QHttpServerRouterViewTraits<const char* (*)(), false>; Args = {const char (&)[2]}]’ /home/user/Qt/6.4.3/gcc_64/include/QtHttpServer/qhttpserver.h:125:71: required from ‘bool QHttpServer::routeHelper(QtPrivate::IndexesList<I ...>, Args&& ...) [with Rule = QHttpServerRouterRule; ViewHandler = const char* (*)(); ViewTraits = QHttpServerRouterViewTraits<const char* (*)(), false>; int ...I = {0}; Args = {const char (&)[2], const char* (*)()}]’ /home/user/Qt/6.4.3/gcc_64/include/QtHttpServer/qhttpserver.h:69:58: required from ‘bool QHttpServer::route(Args&& ...) [with Rule = QHttpServerRouterRule; Args = {const char (&)[2], const char* (*)()}]’ ../httptest/main.cpp:16:15: required from here /home/user/Qt/6.4.3/gcc_64/include/QtHttpServer/qhttpserverviewtraits_impl.h:42:56: error: ‘operator()’ is not a member of ‘std::remove_cv<const char* (* const)()>::type’ {aka ‘const char* (*)()’} 42 | struct FunctionTraits : public FunctionTraits<decltype(&q20::remove_cvref_t<T>::operator())>{}; | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /home/user/Qt/6.4.3/gcc_64/include/QtHttpServer/qhttpserverviewtraits_impl.h: In instantiation of ‘struct QtPrivate::ViewTraits<const char* (* const&)(), false>’: /home/user/Qt/6.4.3/gcc_64/include/QtHttpServer/qhttpserverrouterviewtraits.h:18:8: required from ‘struct QtPrivate::RouterViewTraitsHelper<const char* (* const&)(), false>’ /home/user/Qt/6.4.3/gcc_64/include/QtHttpServer/qhttpserverrouterviewtraits.h:122:11: required from ‘struct QHttpServerRouterViewTraits<const char* (* const&)(), false>’ /home/user/Qt/6.4.3/gcc_64/include/QtHttpServer/qhttpserverrouter.h:57:39: required by substitution of ‘template<class ViewHandler, class ViewTraits> typename ViewTraits::BindableType QHttpServerRouter::bindCaptured(ViewHandler&&, const QRegularExpressionMatch&) const [with ViewHandler = const char* (* const&)(); ViewTraits = QHttpServerRouterViewTraits<const char* (* const&)(), false>]’ /home/user/Qt/6.4.3/gcc_64/include/QtHttpServer/qhttpserver.h:135:59: required from ‘bool QHttpServer::routeImpl(Args&& ..., ViewHandler&&) [with Rule = QHttpServerRouterRule; ViewHandler = const char* (*)(); ViewTraits = QHttpServerRouterViewTraits<const char* (*)(), false>; Args = {const char (&)[2]}]’ /home/user/Qt/6.4.3/gcc_64/include/QtHttpServer/qhttpserver.h:125:71: required from ‘bool QHttpServer::routeHelper(QtPrivate::IndexesList<I ...>, Args&& ...) [with Rule = QHttpServerRouterRule; ViewHandler = const char* (*)(); ViewTraits = QHttpServerRouterViewTraits<const char* (*)(), false>; int ...I = {0}; Args = {const char (&)[2], const char* (*)()}]’ /home/user/Qt/6.4.3/gcc_64/include/QtHttpServer/qhttpserver.h:69:58: required from ‘bool QHttpServer::route(Args&& ...) [with Rule = QHttpServerRouterRule; Args = {const char (&)[2], const char* (*)()}]’ ../httptest/main.cpp:16:15: required from here /home/user/Qt/6.4.3/gcc_64/include/QtHttpServer/qhttpserverviewtraits_impl.h:65:11: error: ‘ArgumentCount’ is not a member of ‘QtPrivate::FunctionTraits<const char* (* const&)()>’ 65 | using ArgumentIndexes = typename Indexes<FTraits::ArgumentCount>::Value; | ^~~~~~~~~~~~~~~ In file included from /home/user/Qt/6.4.3/gcc_64/include/QtHttpServer/qhttpserverrouter.h:8, from /home/user/Qt/6.4.3/gcc_64/include/QtHttpServer/qhttpserver.h:9, from /home/user/Qt/6.4.3/gcc_64/include/QtHttpServer/QHttpServer:1, from ../httptest/main.cpp:2: /home/user/Qt/6.4.3/gcc_64/include/QtHttpServer/qhttpserverrouterviewtraits.h: In instantiation of ‘struct QHttpServerRouterViewTraits<const char* (* const&)(), false>’: /home/user/Qt/6.4.3/gcc_64/include/QtHttpServer/qhttpserverrouter.h:57:39: required by substitution of ‘template<class ViewHandler, class ViewTraits> typename ViewTraits::BindableType QHttpServerRouter::bindCaptured(ViewHandler&&, const QRegularExpressionMatch&) const [with ViewHandler = const char* (* const&)(); ViewTraits = QHttpServerRouterViewTraits<const char* (* const&)(), false>]’ /home/user/Qt/6.4.3/gcc_64/include/QtHttpServer/qhttpserver.h:135:59: required from ‘bool QHttpServer::routeImpl(Args&& ..., ViewHandler&&) [with Rule = QHttpServerRouterRule; ViewHandler = const char* (*)(); ViewTraits = QHttpServerRouterViewTraits<const char* (*)(), false>; Args = {const char (&)[2]}]’ /home/user/Qt/6.4.3/gcc_64/include/QtHttpServer/qhttpserver.h:125:71: required from ‘bool QHttpServer::routeHelper(QtPrivate::IndexesList<I ...>, Args&& ...) [with Rule = QHttpServerRouterRule; ViewHandler = const char* (*)(); ViewTraits = QHttpServerRouterViewTraits<const char* (*)(), false>; int ...I = {0}; Args = {const char (&)[2], const char* (*)()}]’ /home/user/Qt/6.4.3/gcc_64/include/QtHttpServer/qhttpserver.h:69:58: required from ‘bool QHttpServer::route(Args&& ...) [with Rule = QHttpServerRouterRule; Args = {const char (&)[2], const char* (*)()}]’ ../httptest/main.cpp:16:15: required from here /home/user/Qt/6.4.3/gcc_64/include/QtHttpServer/qhttpserverrouterviewtraits.h:122:11: error: no type named ‘ReturnType’ in ‘using FunctionTraits = using FTraits = struct QtPrivate::FunctionTraits<const char* (* const&)()>’ {aka ‘struct QtPrivate::FunctionTraits<const char* (* const&)()>’} 122 | using ReturnType = typename Helpers::FunctionTraits::ReturnType; | ^~~~~~~~~~ In file included from /home/user/Qt/6.4.3/gcc_64/include/QtHttpServer/QHttpServer:1, from ../httptest/main.cpp:2: /home/user/Qt/6.4.3/gcc_64/include/QtHttpServer/qhttpserver.h: In instantiation of ‘bool QHttpServer::routeImpl(Args&& ..., ViewHandler&&) [with Rule = QHttpServerRouterRule; ViewHandler = const char* (*)(); ViewTraits = QHttpServerRouterViewTraits<const char* (*)(), false>; Args = {const char (&)[2]}]’: /home/user/Qt/6.4.3/gcc_64/include/QtHttpServer/qhttpserver.h:125:71: required from ‘bool QHttpServer::routeHelper(QtPrivate::IndexesList<I ...>, Args&& ...) [with Rule = QHttpServerRouterRule; ViewHandler = const char* (*)(); ViewTraits = QHttpServerRouterViewTraits<const char* (*)(), false>; int ...I = {0}; Args = {const char (&)[2], const char* (*)()}]’ /home/user/Qt/6.4.3/gcc_64/include/QtHttpServer/qhttpserver.h:69:58: required from ‘bool QHttpServer::route(Args&& ...) [with Rule = QHttpServerRouterRule; Args = {const char (&)[2], const char* (*)()}]’ ../httptest/main.cpp:16:15: required from here /home/user/Qt/6.4.3/gcc_64/include/QtHttpServer/qhttpserver.h:135:59: error: no matching function for call to ‘QHttpServerRouter::bindCaptured(const char* (* const&)(), const QRegularExpressionMatch&)’ 135 | auto boundViewHandler = router()->bindCaptured(viewHandler, match); | ~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~ In file included from /home/user/Qt/6.4.3/gcc_64/include/QtHttpServer/qhttpserver.h:9, from /home/user/Qt/6.4.3/gcc_64/include/QtHttpServer/QHttpServer:1, from ../httptest/main.cpp:2: /home/user/Qt/6.4.3/gcc_64/include/QtHttpServer/qhttpserverrouter.h:57:39: note: candidate: ‘template<class ViewHandler, class ViewTraits> typename ViewTraits::BindableType QHttpServerRouter::bindCaptured(ViewHandler&&, const QRegularExpressionMatch&) const’ 57 | typename ViewTraits::BindableType bindCaptured(ViewHandler &&handler, | ^~~~~~~~~~~~ /home/user/Qt/6.4.3/gcc_64/include/QtHttpServer/qhttpserverrouter.h:57:39: note: substitution of deduced template arguments resulted in errors seen above make: *** [Makefile:834: main.o] Error 1 14:38:56: The process "/usr/bin/make" exited with code 2. Error while building/deploying project httptest (kit: Desktop Qt 6.4.3 GCC 64bit) When executing step "Make" 14:38:56: Elapsed time: 00:01.
-
@Tarae said in QHttpServer: use function pointer as ViewHandler:
const char * responseFunction
Try without const:
char * responseFunction(...
-
@Tarae
I'm only guessing, but since those parameters are optional try specifying defaults for them. Assuming you can do that in a free/C function, I don't know.The
const char *
for the return value is correct.BTW: if all else fails, you can always make it a lambda like the examples show and have that lambda simply call your free function....
-
@JonB specifying defaults for
const QHttpServerRequest &
andQHttpServerResponder &&
is not that easy. But I don't feel like it will solve my problem.
I know I can use a lambda to call my function, but the documentation says function pointer, so I want to figure it out. -
From my pov a plain function is currently not possible so either the documentation is wrong or the implementation. Since there is an easy workaround for it I would guess the solution is to adjust the documentation. Please create a bug report for it and post the bug number here.
-
If this is what @Christian-Ehrlicher says, no wonder we could not figure it yesterday! :)
-
A plain function does not work but a std::function<> since the template magic expects a callable:
std::function<const char* ()> resp = &responseFunction; server.route("/", resp);
-
@Christian-Ehrlicher
I am whistling in the dark here, but I'm a student of C++ so I am interested. I am not as expert as you. The issue is "a callable". I do not have Qt6 so cannot testQHttpServer::route()
If you don't want to use a lambda orstd::function
here, could you use something like:struct callable { const char *operator()() const { std::cout << "Hello World from a callable!\n"; return "Hello World!"; } }; const callable responseFunction; server.route("/", &responseFunction);
Maybe this is the sort of thing a lambda or
std::function()
does which is different from a plain function? -
@Christian-Ehrlicher I've created a bug report: https://bugreports.qt.io/browse/QTBUG-112484
-
And fixed
-