SFML community forums

Help => General => Topic started by: Flash619 on November 06, 2012, 02:50:24 am

Title: VS 11, and variadic templates with std::thread
Post by: Flash619 on November 06, 2012, 02:50:24 am
This is not related to SFML, but I don't belong to any other coding community so I thought I would ask here. ^_^

I am trying to start up a thread with "std::thread" like:

std::thread RunningLoadingScreen(RunLoadingScreen,CurrLoadScreen,glWindow);
 

The function looks like:

void LoadingScreens::RunLoadingScreen(LoadingScreen LS,EngineWindow& glWindow)
{
        if(LS.IsStatic){
                sf::Sprite LSS;
                LSS.setTexture(texture.getTexture(LS.ResourcePath));
                LSS.setPosition(glWindow.GetCenter().x,glWindow.GetCenter().y);
                glWindow.draw(LSS);
                glWindow.display();
        }else{
                        sfe::Movie LSM;
                        if(!LSM.openFromFile(LS.ResourcePath))
                        {
                                return;
                        }
                        LSM.setPosition(glWindow.GetCenter().x,glWindow.GetCenter().y);
                        LSM.play();
                        while(IsLoading)
                        {
                                glWindow.draw(LSM);
                                glWindow.display();
                        }
        }
}
 

But my compiler always spits the error:

Quote
std::thread::thread No overloaded function takes three arguments.

I looked it up and apparentlyVS 11 does not support Variadic Templates (http://connect.microsoft.com/VisualStudio/feedback/details/747001/c-variadic-templates-fail-to-compile-vs2012). So I wanted to ask if there is any way around this? I found some people mentioning the use of adding "#define" to define stuff for the preproccesor but I was unable to make out exactly what it was they were talking about, or how to do it.

So any help is as always, 100% appreciated. If you need any info just ask! :) I look forward to a great discussion.  ;D
Title: AW: VS 11, and variadic templates with std::thread
Post by: eXpl0it3r on November 06, 2012, 10:45:10 am
Easiest solution: stop using VS. ;)
I've pretty much abandoned VS since they feel like C++11 is nothing urgent...

Otherwise you can create a struct/class that hold all your wanted data and pass everything as one argument.

Btw for generic C++/programming question I can suggest to you StackOverflow. There you'll get answers quickly and often from people with quite a bit experience.
Title: Re: AW: VS 11, and variadic templates with std::thread
Post by: Flash619 on November 06, 2012, 03:39:46 pm
Easiest solution: stop using VS. ;)
I've pretty much abandoned VS since they feel like C++11 is nothing urgent...

Otherwise you can create a struct/class that hold all your wanted data and pass everything as one argument.

Btw for generic C++/programming question I can suggest to you StackOverflow. There you'll get answers quickly and often from people with quite a bit experience.

What would you recommend instead of VS?

I've seen good and bad reports for netbeans, and I have also heard good things from eclipse *and use eclipse for java* but have no experience with it for C++

I've also heard mixed reports for code blocks.
Title: Re: VS 11, and variadic templates with std::thread
Post by: Laurent on November 06, 2012, 03:48:48 pm
It seems that the november version of the compiler adds support for variadic templates
http://blogs.msdn.com/b/vcblog/archive/2012/11/02/visual-c-c-11-and-the-future-of-c.aspx
Title: Re: VS 11, and variadic templates with std::thread
Post by: Flash619 on November 06, 2012, 03:53:47 pm
It seems that the november version of the compiler adds support for variadic templates
http://blogs.msdn.com/b/vcblog/archive/2012/11/02/visual-c-c-11-and-the-future-of-c.aspx

But if I switch my compiler, I don't think I'll be able to compile for windows XP anymore as I had it set to "Visual Studio 2012 - Windows XP (v110_xp)

>.<

I am not sure if this version of the compiler "120_CTP" includes XP support.
Title: Re: VS 11, and variadic templates with std::thread
Post by: eXpl0it3r on November 06, 2012, 03:56:55 pm
What would you recommend instead of VS?

I've seen good and bad reports for netbeans, and I have also heard good things from eclipse *and use eclipse for java* but have no experience with it for C++

I've also heard mixed reports for code blocks.
As a matter of fact Microsoft announced (http://blogs.msdn.com/b/vcblog/archive/2012/11/02/visual-c-c-11-and-the-future-of-c.aspx) a CTP (customer technology previews) which should support more C++11 features a few days ago. But for a really official support it will still take longer... - Uhm Laurent was faster. :D

What to choose is a controversial topic and nearly all the arguments are just about personal preferences.
At the moment I'm using Code::Blocks to develop, but obviously not the very old official release from 2010 (iirc), but the nightly builds that come out every week or so. One just needs to download the new build and replace it with the old one, the settings etc. will all be preserved.

Personally I don't like Eclipse that much, since it's running with Java and uses quite a bit more resources than it needs to, but since I haven't really used it, I can't judge more about it. Neither can I comment on Netbeans.
If you feel like it then gVim + terminal is always a nice way, although for a new beginner not the most comfortable one.

More important than the IDE discussion is the compiler (version). I'd really like to see a working Clang compiler on Windows that comes with mostly all the essential libraries (so one could use SFML with it), but this will probably take a few more years...
So you're stuck with GCC/MinGW. The official/original MinGW32 (http://www.mingw.org/) project is a bit behind with the compiler version (4.6ish) and thus you might want to take a look at the TDM MinGW32 (http://tdm-gcc.tdragon.net/) port. If you feel like getting a bit into a more experimental world, then you should most definitely check out the MinGW-w64 (http://mingw-w64.sourceforge.net/) port, which reorganizes the MinGW32 project and additionally provides a 64bit compiler. But as I said the 264 project isn't the most stable and you can run into some problems which can't really get resolved atm.

What I've left out is the Cygwin (http://cygwin.com/) vs 'native' discussion. Cygwin is a very nice to get the Linux world to Windows, but the problem is, that it's not exactly a 'native' Windows build, but you'll have to provide a Cygwin 'runtime' library. Next to this, their compiler (gcc) isn't really uptodate either. So I'd rather suggest to use MSYS (http://www.mingw.org/wiki/MSYS). I only use Cygwin for Git interaction and other nice Linux features.
Title: Re: VS 11, and variadic templates with std::thread
Post by: Flash619 on November 06, 2012, 04:03:45 pm
So an update with the Nov compiler, now I get an error telling me:

Quote
Error   1   error C3867: 'LoadingScreens::RunLoadingScreen': function call missing argument list; use '&LoadingScreens::RunLoadingScreen' to create a pointer to member

........I don't see how its missing a argument list... I passed arguments with the thread.
Title: Re: VS 11, and variadic templates with std::thread
Post by: Laurent on November 06, 2012, 04:08:53 pm
The compiler explicitely gives the solution
Quote
use '&LoadingScreens::RunLoadingScreen' to create a pointer to member
Title: Re: VS 11, and variadic templates with std::thread
Post by: Flash619 on November 06, 2012, 04:31:52 pm
The compiler explicitely gives the solution
Quote
use '&LoadingScreens::RunLoadingScreen' to create a pointer to member

That leads me to this error:
Quote
Error   3   error C2064: term does not evaluate to a function taking 2 arguments   C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\functional   1152   1   Genesis (Microsoft Visual C++ Compiler Nov 2012 CTP)

I think my problem is in how I laid out my arguments for the thread. This is the first time I have ever touched std::thread, so I really don't know what it wants me to do at this point. Every tutorial I find online, theirs works just fine. >.>
Title: Re: VS 11, and variadic templates with std::thread
Post by: Laurent on November 06, 2012, 04:35:56 pm
Hum, in fact they said they updated the compiler, but not the standard library. So the std::thread constructor that you want to use is probably still not available.
Title: Re: VS 11, and variadic templates with std::thread
Post by: Nexus on November 06, 2012, 04:37:10 pm
So I wanted to ask if there is any way around this?
std::bind()

Easiest solution: stop using VS.
I have yet to find an IDE that can compete with Visual Studio + Visual Assist X ;)

It seems that the november version of the compiler adds support for variadic templates
http://blogs.msdn.com/b/vcblog/archive/2012/11/02/visual-c-c-11-and-the-future-of-c.aspx
That sounds great, thanks for the information!
Title: Re: VS 11, and variadic templates with std::thread
Post by: Flash619 on November 06, 2012, 04:38:15 pm
So I wanted to ask if there is any way around this?
std::bind()

Easiest solution: stop using VS.
I have yet to find an IDE that can compete with Visual Studio + Visual Assist X ;)

Bind() I have tried, it throws about 14 errors. ^^;;;;

Running it like:

std::thread RunningLoadingScreen(std::bind(&LoadingScreens::RunLoadingScreen,CurrLoadScreen,glWindow));
 

Quote
Error   3   error C2064: term does not evaluate to a function taking 2 arguments   C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\functional   1152   1   Genesis (Microsoft Visual C++ Compiler Nov 2012 CTP)

Running it like:
std::thread RunningLoadingScreen(&LoadingScreens::RunLoadingScreen,CurrLoadScreen,glWindow);
 

Quote
Error   3   error C2064: term does not evaluate to a function taking 2 arguments   C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\functional   1152   1   Genesis (Microsoft Visual C++ Compiler Nov 2012 CTP)

Running it like:

std::thread RunningLoadingScreen(std::bind(LoadingScreens::RunLoadingScreen,CurrLoadScreen,glWindow));
 

Quote
Error   102   error C1003: error count exceeds 100; stopping compilation.

............Not sure what to use for threading now...I really would want to use std::thread if I can, but it would seem that's a impossibility at this point.
Title: Re: VS 11, and variadic templates with std::thread
Post by: Nexus on November 06, 2012, 04:41:41 pm
Please come up with a meaningful error description if you want help. And avoid full quotes if the post is just above, even more if you refer only to a part of it.

How did you try bind()? Did you include <functional>?

Edit: Of course it is not impossible to use std::thread, you just have to do it correctly. The this pointer must be specified to bind a member function to an object, and references must be passed via std::ref. You can also use lambda expressions.
Title: Re: VS 11, and variadic templates with std::thread
Post by: Flash619 on November 06, 2012, 04:52:03 pm
How did you try bind()? Did you include <functional>?

The this pointer must be specified to bind a member function to an object, and references must be passed via std::ref.
In that last part.... are you talking about "std::bind" when you talk about it being specified to bind a member function?


I had seen examples of people who recommended the use of "std::bind" but was unaware of the use of "<functional>" template. I also did see some people use "std::ref" but I was, and still do not know the proper usage of it, so I stayed away from it.

Also, according to several online tutorials that I found, this is a correct method of doing it, but it seems I have to change it to different methods for VS.  Right here (http://www.justsoftwaresolutions.co.uk/threading/multithreading-in-c++0x-part-2-function-objects-and-arguments.html), is a perfectly good example that when I try to implement it for my uses, does not work. I will note however, that they did show the use of "std::bind". They also showed that it was not required but I don't think they listed what IDE/compiler they used.
Title: Re: VS 11, and variadic templates with std::thread
Post by: Nexus on November 06, 2012, 05:00:00 pm
In that last part.... are you talking about "std::bind" when you talk about it being specified to bind a member function?
Yes, I spoke about std::bind and the fact that you have to pass the this pointer of the object on which you want to call the member function.

I had seen examples of people who recommended the use of "std::bind" but was unaware of the use of "<functional>" template.
<functional> is a header, as the word "include" suggests.

I also did see some people use "std::ref" but I was, and still do not know the proper usage of it, so I stayed away from it.
A better idea would be to learn it ;)
See the documentation of Boost.Bind, for example.

By the way, instead of bind(), you can achieve the same functionality with a functor (=function object). It is simpler if you don't know the standard library functionals, but it requires more code.
Title: Re: VS 11, and variadic templates with std::thread
Post by: Flash619 on November 06, 2012, 05:15:23 pm
Yes, I spoke about std::bind and the fact that you have to pass the this pointer of the object on which you want to call the member function.
...Do you mean something like this?
std::thread RunningLoadingScreen(std::bind(&LoadingScreens::RunLoadingScreen,CurrLoadScreen,glWindow));
 

A better idea would be to learn it ;)
See the documentation of Boost.Bind, for example.
But what does Boost.Bind have to do with std::ref ? o.O;

I tried shoving in std::ref() like:
std::thread RunningLoadingScreen(&LoadingScreens::RunLoadingScreen,std::ref(CurrLoadScreen,glWindow));
 

Just to see what would happen, but it tells me that it does not match the arguments list. *I figured something like that would happen, but I had to try.*

By the way, instead of bind(), you can achieve the same functionality with a functor (=function object). It is simpler if you don't know the standard library functionals, but it requires more code.

I would rather just *try* to learn the usual way of doing it instead of having to go even further around obstacles. That's why it probably seems like I'm asking stupid questions. XD I'll admit I don't know everything. >_>

EDIT

Also I tried multiples of std::ref to try to find the proper argument method.
std::thread RunningLoadingScreen(&LoadingScreens::RunLoadingScreen,std::ref(CurrLoadScreen),std::ref(glWindow));
 

Seems to make it quiet down, but I'm almost certain its incorrect, and it still gives me the "does not evaluate to a function taking two arguments" error.
Title: Re: VS 11, and variadic templates with std::thread
Post by: Nexus on November 06, 2012, 05:23:22 pm
It doesn't make sense to explain specific parts such as std::ref() if you haven't understood the whole concept of functionals. You should inform yourself about the following topics, in this order:
For the problem shown here, the first point is enough, the others offer only convenience. The C++11 standard library has adopted many parts from Boost, so the usage is often the same.
Title: Re: VS 11, and variadic templates with std::thread
Post by: Flash619 on November 06, 2012, 05:31:02 pm
It doesn't make sense to explain specific parts such as std::ref() if you haven't understood the whole concept of functionals.

But I'm not really asking to know about std::ref(), just really focusing on how I can actually get my thread to start up so it doesn't take me 15 hours to get a simple loading screen setup. >_> *and trust me, it probably will take longer than that*.

I'm really just trying to figure out, how to make the lovely "error C2064: term does not evaluate to a function taking 2 arguments" that has been bugging my error log for the last 45min, go away. Sure it would be awesome to sit down with a huge book about functionals and references, and binding objects. But I usually learn things backwards. *mainly because I cant actually retain knowledge from reading books *like in my sociology class* * So forgive me if I seem like I'm rushing in, I'm really not. Well, to me I'm not anyways.

Usually my process is as follows:

That pretty much sums up how I learn things, and retain the information.
Title: Re: VS 11, and variadic templates with std::thread
Post by: Nexus on November 06, 2012, 05:46:28 pm
Usually my process is as follows:
  • Start programming.
  • Run into an error.
  • Spend a while fixing the error.
  • Finally find a workable solution to the error.
  • Inspect how the solution works.
  • Do research as to why it works, and how it works.
  • Remember it for the future.
  • Continue programming.
Trial and error is a very bad approach in C++. Not only that you run into errors all the time, but by "fixing" them (i.e. finding workarounds), you don't know learn how to do things the right way, and often there is even the possibility that you introduce bugs (undefined behavior, for example).

The time you waste pointlessly in "fixing" and asking in forums would be much better invested in reading books. Of course, not everybody learns well from books, but don't use this as an excuse -- there is no way around theory if you want to write good code :)

I don't expect you to learn about Boost.Function and Boost.Bind, that is why I wrote "the first point is enough". Function objects is really something every C++ programmer should know, so take the time to learn it. This is not something you use once for the thread and then never again, functors will certainly prove useful. Already because STL algorithms operate on them.
Title: Re: VS 11, and variadic templates with std::thread
Post by: Flash619 on November 06, 2012, 05:53:35 pm
The time you waste pointlessly in "fixing" and asking in forums would be much better invested in reading books. Of course, not everybody learns well from books, but don't use this as an excuse -- there is no way around theory if you want to write good code :)

I don't expect you to learn about Boost.Function and Boost.Bind, that is why I wrote "the first point is enough". Function objects is really something every C++ programmer should know, so take the time to learn it. This is not something you use once for the thread and then never again, functors will certainly prove useful. Already because STL algorithms operate on them.

Well of course I want to learn just about everything eventually. But for now I'm trying to focus on why my thread won't work. Yea trial and error is a pain. But how else would I ever find out things don't work that way? Sure I can learn a bunch about functors, but it wont actually come out and tell me "this is why your thread is not working." So if I don't understand how the thread is supposed to work, and why my threads arguments are not working now, it would just teach me about functors, then afterwords, I would be in the same situation I am now, only I would know functors. Make sense?
Title: Re: VS 11, and variadic templates with std::thread
Post by: Nexus on November 06, 2012, 06:13:08 pm
Make sense?
No.

The reason why your thread is not working is the wrong usage of functors. It has absolutely nothing to do with threading. This problem may reoccur in various other situations, and exactly because of that it doesn't help you if you only get something working without understanding it.

And instead of continuing this meaningless discussion, you should finally realize that you would have already learned everything you need in the time you have wasted so far, and additionally you could use the gained knowledge in the future for other problems. So please be wise enough and spend 15 minutes on the usage and definition of functors, this is well-invested time.
Title: Re: VS 11, and variadic templates with std::thread
Post by: Flash619 on November 06, 2012, 06:37:31 pm
And instead of continuing this meaningless discussion, you should finally realize that you would have already learned everything you need in the time you have wasted so far, and additionally you could use the gained knowledge in the future for other problems. So please be wise enough and spend 15 minutes on the usage and definition of functors, this is well-invested time.

I highly doubt that in one hours time, I could have read up on everything, deciphered and understood what they actually mean in the documentation, and somehow figured out my problem and solved it. Just as I don't think this discussion is meaningless. I see several good things that have already come from it. I'm planning on reading through it all, but can't help but wonder *Will I actually remember this at a later point in time.*

But for the sake of pleasing you I will read up on the above topic's in the order in which you listed them, and get back to you with questions *if I find any*.

EDIT

Found a really nice article (http://www.tenouk.com/download/pdf/Module38.pdf) about functors. ^_^
Title: Re: VS 11, and variadic templates with std::thread
Post by: mercurio7891 on November 06, 2012, 08:47:04 pm
A bit late to this post. Your original code don't work because std::thread requires a function to execute not a member function.

void LoadingScreens::RunLoadingScreen(LoadingScreen LS,EngineWindow& glWindow);

is a member function of class LoadingScreens. Now in C++ in order to execute a member function (i.e non-static function) there must aways be a calling class object. Notice how to call a class member function, you have to create a class object and call using it e.g

LoadingScreens screens_1;
LoadingScreens* screens_2 = new LoadingScreens;
screens_1.SuperFuncOne();
screens_2->SuperFuncOne();

by simply passing in only the function signature &LoadingScreen::RunLoadingScreen to the std:thread constructor, it still requires a vital piece of information to run the member. Which is of course from which class object should this member function be called from?

Following Nexus point, this is where stuff from the <functional> header comes into play. First you have to convert the member function into a regular function. this is where std::mem_fn is used. By calling

auto thread_friendly_func = std::mem_fn(&LoadingScreens::RunLoadingScreen);

thread_friendly_func is now a regular function pointer which points to a function similar to below:

MyNewFunc(LoadingScreens* object, LoadingScreen LS,EngineWindow& glWindow);

Now that we have a regular function, we can easily pass that function signature to std::thread and set the arguments for it.

std::thread RunningLoadingScreen(thread_friendly_func, screens_1, CurrLoadScreen, glWindow);

P.S I have no idea if in your original post LoadingScreens and LoadingScreen are the different or just a typo error. I treat them as different.

regards
Title: Re: VS 11, and variadic templates with std::thread
Post by: Flash619 on November 06, 2012, 09:06:14 pm
P.S I have no idea if in your original post LoadingScreens and LoadingScreen are the different or just a typo error. I treat them as different.

Oh, that was because I didn't show the header file. ^^;; LoadingScreen is a struct that holds variables for each type of loading screen, and LoadingScreens is the name of the class. :)

But wouldn't you have to initialize "thread_friendly_func" first? Either that or microsoft claims the error is because it is being initialized by itself which I don't really see happening.

Because I looked up, and tried what you said. but It still gives two errors:

Quote
Error   2   error C3536: 'RunLoadingScreenT': cannot be used before it is initialized   
Error   1   error C3867: 'LoadingScreens::RunLoadingScreen': function call missing argument list; use '&LoadingScreens::RunLoadingScreen' to create a pointer to member

Thank you for your help tho, because even after reading about functors, I'm still pretty much clueless as to how they are relevant to what I am doing, or even how to make this work. I mean, I completely understand the operator() and functors.......but I have not functors in any of my code so I fail to see how its aparent to my problem..... *sigh..... I'm honestly starting to wonder if I'll actually ever get threads working... I mean. All I wanted was a simple thread to work. I shutter to think if I wanted to pass four arguments XD, But really, every example I find they don't have to switch out functions and such. Or do half of all of this work. And here I do all of this work, and it still doesn't work. Its rather frustrating at times.
Title: Re: VS 11, and variadic templates with std::thread
Post by: Flash619 on November 06, 2012, 10:02:15 pm
I mean, here so that you can see the whole picture:

LoadingScreens.cpp
#include "stdafx.h"
#include "LoadingScreens.h"
void LoadingScreens::Display(_LST ST,EngineWindow& glWindow)
{
        IsLoading=true;

        LoadingScreen CurrLoadScreen;

        switch(ST){
        case GNS_Cold:
                CurrLoadScreen = GNS_Cold_F();
                break;
        default:
                return;
        }
        LoadingScreens loadingScreens;
        auto RunLoadingScreenT = std::mem_fn(&LoadingScreens::RunLoadingScreen);
        std::thread t(RunLoadingScreenT,loadingScreens,CurrLoadScreen,glWindow);
}
LoadingScreens::LoadingScreen LoadingScreens::GNS_Cold_F()
{
        LoadingScreen GNS_Cold_LS;
        GNS_Cold_LS.LST_Alias = LoadingScreens::_LST::GEN_Cold;
    GNS_Cold_LS.IsStatic = true;
        GNS_Cold_LS.ResourcePath = "Resource/LoadingScreens/Genesis/Cold/Loading_Main.png";

        return GNS_Cold_LS;
}
void LoadingScreens::RunLoadingScreen(LoadingScreen LS,EngineWindow& glWindow) //This should run in a thread.
{
        if(LS.IsStatic){
                sf::Sprite LSS;
                LSS.setTexture(texture.getTexture(LS.ResourcePath));
                LSS.setPosition(glWindow.GetCenter().x,glWindow.GetCenter().y);
                glWindow.draw(LSS);
                glWindow.display();
        }else{
                        sfe::Movie LSM;
                        if(!LSM.openFromFile(LS.ResourcePath))
                        {
                                return;
                        }
                        LSM.setPosition(glWindow.GetCenter().x,glWindow.GetCenter().y);
                        LSM.play();
                        while(IsLoading)
                        {
                                glWindow.draw(LSM);
                                glWindow.display();
                        }
        }
}

 

LoadingScreens.h
#ifndef LOADINGSCREENS_H
#define LOADINGSCREENS_H
#include "stdafx.h"
#include "SpriteUtilities.h"
#include <SFML\Graphics.hpp>
#include <thread>
#include <sfeMovie\Movie.hpp>
#include <functional>
class LoadingScreens{
        Texture texture;
public:
        enum _LST{GNS_Cold,GNS_Anim,GEN_Cold,GEN_Anim,LVL_GEN_Cold,LVL_GEN_Anim};
        void Display(_LST,EngineWindow&);
        void Recall();
private:
        struct LoadingScreen
        {
        public:
                _LST LST_Alias;
                std::string ResourcePath;
                bool IsStatic;
                bool IsGeneric;
                std::string Args;
        };

        bool IsLoading;

        LoadingScreen GNS_Cold_F();

        void RunLoadingScreen(LoadingScreen,EngineWindow&);

};
#endif
 

I mean. I really don't see why this is not working at this point. I personally think this should have worked a long time ago. but as always, I am missing some small key of information that's probably ruining the entire thing.

EDIT

So I have it working with:

std::thread t(&LoadingScreens::RunLoadingScreen,&loadingScreens,CurrLoadScreen,glWindow);
 

But now I get errors from a sf::NonCopyable. So It must be trying to make a copy of "glWindow" but glWindow has inheritance with sf::renderWindow which explains where the error comes from. Is there a way to pass it as a reference?

EDIT

AHA! I knew it! I feel so proud. XD std::ref, I love you.

I will now continue to learn about functors and base C++ knowledge.