1

So I was reading this thread: C++ How to store a parameter pack as a variable

The answer didn't really help me (I wasn't sure on how to implement it)

What I'm trying to create is a Thread class that has arguments, the current way I do it the arguments need to be able to be stored as members, for them to be passed onto the member function.

Here is my current Thread class: (I want All the FuncArgs to be able to be stored as members, so they can be passed to the member function in Run)

template<class _Ty, typename...FuncArgs>
    class YThread
{
private:

    typedef YVoid(_Ty::* YMethod)();

    HANDLE _myThread_handle;
    DWORD  _myThread_id;
    _Ty* _myObject;
    YMethod _myMethod;



private:
    static YVoid Run(YPointer thread_obj)
    {
        YThread<_Ty>* thread = (YThread<_Ty>*)thread_obj;
        thread->_myObject->*thread->_myMethod();
    }
    YThread(const YThread<_Ty>& Other) = delete;
    YThread<_Ty>& operator=(const YThread<_Ty>& other) = delete;

public: // Starters
    YThread()
    {}
    YThread(_Ty* object, YVoid(_Ty::* method)())
    {
        _myObject = object;
        _myMethod = method;
        Start();
    }

    ~YThread()
    {
        if (_myThread_handle)
            CloseHandle(_myThread_handle);
    }

    YBool Start()
    {
        _myThread_handle = CreateThread(
            0, 0,
            (LPTHREAD_START_ROUTINE)YThread<_Ty>::Run,
            this,
            0, &_myThread_id);
    }

    YBool Start(_Ty* object, YVoid(_Ty::* method)())
    {
        _myObject = object;
        _myMethod = method;
        Start();
    }

public: // Other
    YVoid Kill()
    {
        TerminateThread(_myThread_handle, 0);
    }

    YVoid Join()
    {
        WaitForSingleObject(_myThread_handle, INFINITE);
    }

    YBool is_alive()
    {
        DWORD exitCode = 0;
        if (_myThread_handle)
            GetExitCodeThread(_myThread_handle, &exitCode);
        if (exitCode == STILL_ACTIVE)
            return true;
        return false;
    }

};
Community
  • 1
  • 1
Yamiez
  • 39
  • 1
  • 9
  • Does this answer your question? [Is it possible to "store" a template parameter pack without expanding it?](https://stackoverflow.com/questions/4691657/is-it-possible-to-store-a-template-parameter-pack-without-expanding-it) – Sapphire_Brick Jun 14 '20 at 15:41

1 Answers1

0

I assume you are doing this for educational purposes - because otherwise, I would strongly suggest you stop reinventing the wheel and use std::thread as nature intended.

That said - something along these lines, perhaps:

class YThread {
  std::function<void()> thing_to_run;
public:
  template<class Ty, typename... FuncArgs>
  YThread(Ty* object, YVoid(Ty::* method)(FuncArgs...),
          FuncArgs&&... args) {
    thing_to_run = [=](){ (object->*method)(std::forward<FuncArgs>(args)...); };
  }
  // When it comes time to actually run the method, just do
  //   thing_to_run();
};
Igor Tandetnik
  • 50,461
  • 4
  • 56
  • 85
  • Yes its mainly for educational purposes and learning, I enjoy learnign new things and experimenting alot! I'll try this thanks! =] – Yamiez Oct 31 '15 at 03:51
  • std::forward brings wierd errors (I know I'm supposed to use, I've used it in my other framework parts), but here its giving wierd conversion errors... `template YVoid Start(_Ty* object, YVoid(_Ty::* method)(Args...), Args...args) { _myFunction = [=]() { (object->*method) (std::forward(args)...); };` – Yamiez Oct 31 '15 at 04:15
  • I like [the experimenting alot](http://hyperboleandahalf.blogspot.com/2010/04/alot-is-better-than-you-at-everything.html), too. Anyway, you forgot to mention the text of the errors. My crystal ball is cloudy lately, I have difficulty reading it off your monitor. – Igor Tandetnik Oct 31 '15 at 04:21
  • Error: http://puu.sh/l403X/324afb43d9.png More clear code: http://puu.sh/l404S/1b32d1d718.png The code being tested: http://puu.sh/l406z/5966354e43.png (The Ctor calls Start, and it works fine without std::forward) – Yamiez Oct 31 '15 at 04:25
  • `Start` is supposed to take `Args&&...args` (note ampersands) – Igor Tandetnik Oct 31 '15 at 04:29
  • Is there any particular reason why the two ampersands are added? Either way it still throws an error: http://puu.sh/l40nN/4303d0d0ad.png – Yamiez Oct 31 '15 at 04:31
  • actually the above error was because the constructor set '_Ty*' as 'MyClass**' and the function then went 'MyClass**'. The error is the same when doing it the correct way (By correct I mean not messing up the Arguments) – Yamiez Oct 31 '15 at 04:35