Pass a method to QtConcurrent::map
-
I will not pretend I understood everything, but did implement the lambda (without
constthough, as usingconst int&and returning a result simply did not work - the vector was not updated at the end).So instead of
auto calculateFunction = [calcParameter1, calcParameter2] (const int & element) -> int { int result = 0; //< Do calculations here return result; };I ended up using
auto calculateFunction = [calcParameter1, calcParameter2] (int & element) -> int { int result = 0; //< Do calculations here element = result; };and then it worked.
-
I will not pretend I understood everything, but did implement the lambda (without
constthough, as usingconst int&and returning a result simply did not work - the vector was not updated at the end).So instead of
auto calculateFunction = [calcParameter1, calcParameter2] (const int & element) -> int { int result = 0; //< Do calculations here return result; };I ended up using
auto calculateFunction = [calcParameter1, calcParameter2] (int & element) -> int { int result = 0; //< Do calculations here element = result; };and then it worked.
I will not pretend I understood everything
Don't worry about it, C++ is riddled with implementation details anyway and to really understand what this low-level stuff does you have to understand quite well how the binary is generated by the compiler and linker, and how the classes/functions/variables are placed in the final binary image and in memory (which also implies a decent knowledge of assembly). While knowing this might be helpful at times it's almost never actually needed in practice.
but did implement the lambda (without const though, as using const int& and returning a result simply did not work - the vector was not updated at the end).
Yes, that was a mistake on my part thinking about
QtConcurrent::mapped, sorry about that. Indeed you can (and should) drop the const modifier of the parameter if you want the sequence to be updated and can simply have your lambda returnvoid.Kind regards.
-
I thought so much! At some point I need to get my nose off the ground and look at the assembly listings of my code to really understand behind the scenes. That helped me a lot years ago when I was learning C++ using Stroustrup's 1st book and Borland C++ 2.0 compiler. Unfortunately I ended up doing almost nothing but Delphi and C# ever since and C++ was well forgotten by now.
Your help and patience with my silly questions is certainly appreciated!
-
I thought so much! At some point I need to get my nose off the ground and look at the assembly listings of my code to really understand behind the scenes. That helped me a lot years ago when I was learning C++ using Stroustrup's 1st book and Borland C++ 2.0 compiler. Unfortunately I ended up doing almost nothing but Delphi and C# ever since and C++ was well forgotten by now.
Your help and patience with my silly questions is certainly appreciated!
-
When I was using Netbeans with GCC under Linux and FreeBSD, the below lambda declared in a descendant of
QDialogworked fine:auto func = [ // 96 x0 = widget.spX0->value(), // 97 y0 = widget.spY0->value(), ] (int& iteration) -> int { // 102 return iteration; };widget.spX0etc are the double spin boxes on the dialog.But now I tried Qt Creator under Win7 and this lambda is throwing a bunch of errors:
newform.cpp:97: error: C2143: syntax error : missing ']' before '=' newform.cpp:97: error: C3481: 'x0': lambda capture variable not found newform.cpp:102: error: C2059: syntax error : ']' newform.cpp:97: error: C2059: syntax error : '='Do I need to switch the language version to C++11 anywhere?
-
When I was using Netbeans with GCC under Linux and FreeBSD, the below lambda declared in a descendant of
QDialogworked fine:auto func = [ // 96 x0 = widget.spX0->value(), // 97 y0 = widget.spY0->value(), ] (int& iteration) -> int { // 102 return iteration; };widget.spX0etc are the double spin boxes on the dialog.But now I tried Qt Creator under Win7 and this lambda is throwing a bunch of errors:
newform.cpp:97: error: C2143: syntax error : missing ']' before '=' newform.cpp:97: error: C3481: 'x0': lambda capture variable not found newform.cpp:102: error: C2059: syntax error : ']' newform.cpp:97: error: C2059: syntax error : '='Do I need to switch the language version to C++11 anywhere?
-
That did not help.
This is what I just downloaded and installed with Qt 5.6 as the only version checked off in the setup:Qt Creator 3.6.1 Based on Qt 5.6.0 (MSVC 2013, 32 bit) Built on Mar 14 2016 09:57:09 From revision d502727b2c Copyright 2008-2016 The Qt Company Ltd. All rights reserved. The program is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.It has
Desktop Qt 5.6.0 MSVC2013 64bit (default)under the Build&Run/Kits
Compiler is set toMicrosoft Visual C++ Compiler 12.0 (amd64). -
That did not help.
This is what I just downloaded and installed with Qt 5.6 as the only version checked off in the setup:Qt Creator 3.6.1 Based on Qt 5.6.0 (MSVC 2013, 32 bit) Built on Mar 14 2016 09:57:09 From revision d502727b2c Copyright 2008-2016 The Qt Company Ltd. All rights reserved. The program is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.It has
Desktop Qt 5.6.0 MSVC2013 64bit (default)under the Build&Run/Kits
Compiler is set toMicrosoft Visual C++ Compiler 12.0 (amd64).@nulluse
Hm. It should've worked. As far as I remember VS 2013 should support most of the C++11 features. Could you post the full compile line for the file you're getting the error at?PS.
Also try declaring the variables for the capture explicitly and see how it goes:int x0 = widget.spX0->value(), y0 = widget.spY0->value(); auto func = [ x0, y0] (int& iteration) -> int { // 102 return iteration; }; -
14:41:29: Running steps for project MandelbrotQt... 14:41:29: Configuration unchanged, skipping qmake step. 14:41:29: Starting: "C:\Qt\Tools\QtCreator\bin\jom.exe" C:\Qt\Tools\QtCreator\bin\jom.exe -f Makefile.Debug cl -c -nologo -Zc:wchar_t -FS -Zi -MDd -GR -W3 -w34100 -w34189 -w44996 -EHsc /Fddebug\MandelbrotQt.pdb -DUNICODE -DWIN32 -DWIN64 -DQT_QML_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -I..\..\MandelbrotQt -I. -IC:\Qt\5.6\msvc2013_64\include -IC:\Qt\5.6\msvc2013_64\include\QtWidgets -IC:\Qt\5.6\msvc2013_64\include\QtGui -IC:\Qt\5.6\msvc2013_64\include\QtANGLE -IC:\Qt\5.6\msvc2013_64\include\QtCore -Idebug -I. -IC:\Qt\5.6\msvc2013_64\mkspecs\win32-msvc2013 -Fodebug\ @C:\Users\user0\AppData\Local\Temp\newform.obj.11028.16.jom newform.cpp ..\..\MandelbrotQt\newform.cpp(97) : error C2143: syntax error : missing ']' before '=' ..\..\MandelbrotQt\newform.cpp(97) : error C3481: 'x0': lambda capture variable not found ..\..\MandelbrotQt\newform.cpp(102) : error C2059: syntax error : ']' ..\..\MandelbrotQt\newform.cpp(97) : error C2059: syntax error : '=' ..\..\MandelbrotQt\newform.cpp(102) : error C2143: syntax error : missing ';' before '{' ..\..\MandelbrotQt\newform.cpp(105) : error C2065: 'x0' : undeclared identifierInteresting enough, I started re-factoring the project to move the computations out of the GUI class, and my new class compiles fine when all I capture is
[this], then refer to the member variables inside the lambda's body.PS: Your workaround works. I will wrap that with
#if defined (Q_OS_WIN)etc.PPS: But now I am getting lots of linker errors similar to this:
newform.obj:-1: error: LNK2019: unresolved external symbol "__declspec(dllimport) public: __cdecl QtConcurrent::ThreadEngineBase::ThreadEngineBase(void)" (__imp_??0ThreadEngineBase@QtConcurrent@@QEAA@XZ) referenced in function "public: __cdecl QtConcurrent::IterateKernel<int *,void>::IterateKernel<int *,void>(int *,int *)" (??0?$IterateKernel@PEAHX@QtConcurrent@@QEAA@PEAH0@Z)Do I need to add linking against a library when working under Windows?
PPPS: This does not make any sense: I am editing the
.profile adding and removingconcurrentfrom QT but still getting this line in the output every time:15:01:05: Configuration unchanged, skipping qmake step. -
@nulluse said:
But now I am getting lots of linker errors similar to this:
Do I need to add linking against a library when working under Windows?Only to the Qt modules as far as I know.
Qt += core gui widgets concurrentetc. It should be working out of the box. -
See my last update - adding
QT += concurrentdoes not change anything as the project thinks configuration is not changing. -
Forcing rebuild does not change anything. The pro file looks like this now:
#------------------------------------------------- # # Project created by QtCreator 2016-04-18T13:54:41 # #------------------------------------------------- QT += core gui concurrent greaterThan(QT_MAJOR_VERSION, 4): QT += widgets TARGET = MandelbrotQt TEMPLATE = app SOURCES += main.cpp\ newform.cpp \ helpers/fileHelper.cpp \ mandelbrot/mandelbrot.cpp HEADERS += newform.h \ helpers/fileHelper.h \ mandelbrot/mandelbrot.h \ ui_newForm.h FORMS += newform.ui LIBS += -lQt5Concurrent CONFIG += c++11The linker is still complaining.
-
Forcing rebuild does not change anything. The pro file looks like this now:
#------------------------------------------------- # # Project created by QtCreator 2016-04-18T13:54:41 # #------------------------------------------------- QT += core gui concurrent greaterThan(QT_MAJOR_VERSION, 4): QT += widgets TARGET = MandelbrotQt TEMPLATE = app SOURCES += main.cpp\ newform.cpp \ helpers/fileHelper.cpp \ mandelbrot/mandelbrot.cpp HEADERS += newform.h \ helpers/fileHelper.h \ mandelbrot/mandelbrot.h \ ui_newForm.h FORMS += newform.ui LIBS += -lQt5Concurrent CONFIG += c++11The linker is still complaining.
@nulluse
It looks okay to me, with the only exception of this line:LIBS += -lQt5Concurrent. You shouldn't need to pass that to the linker, adding theQT += concurrentis enough (qmakewill generate the appropriate include files and linker switches).