Kmeeth
Kmeeth

Reputation: 1

Problems with forwarding arguments to std::thread constructor

I am trying to create a class Thread that aims to wrap std::thread in such a way that it doesn't immmediately start upon construction, but rather has to be started separately. This requires a template constructor, since such is the constructor of std::thread. Here is the code:

class Thread
        {
        public:
            template<class Function, class ... Args>
            Thread(Function&& function, Args&& ... args)
                :myThread(&Thread::wrapper<Function, Args...>, std::forward<Function>(function), std::ref(*this), std::forward<Args>(args)...)
            {
                started.lock();
            }
            void start()
            {
                started.unlock();
            }

        private:
            std::thread myThread;
            std::mutex started;

            template<class Function, class ... Args>
            static void wrapper(Function&& function, Thread& thread, Args&& ... args)
            {
                // Wait until it is started
                thread.started.lock();

                // Execute the function
                function(std::forward<Args>(args) ...);
            }
        };

And this line seems to be the problem: :myThread(&Thread::wrapper<Function&&, Args&&...>, std::forward<Function>(function), std::ref(*this), std::forward<Args>(args)...)

I can't seem to figure out what I did wrong in this instance, since the code won't compile, and there are only 3 (for me) cryptic errors.

Error C2672 'invoke': no matching overloaded function found

Error C2893 Failed to specialize function template 'unknown-type std::invoke(_Callable &&,_Ty1 &&,_Types2 &&...) noexcept()'

Error C2780 'unknown-type std::invoke(_Callable &&) noexcept()': expects 1 arguments - 4 provided

If anyone could help me figure this out, I would greatly appreciate it.

Upvotes: 0

Views: 298

Answers (1)

OznOg
OznOg

Reputation: 4732

replace

:myThread(&Thread::wrapper<Function&&, Args&&...>, std::forward<Function>(function), std::ref(*this), std::forward<Args>(args)...)

by

:myThread(&Thread::wrapper<Function, Args...>, std::forward<Function>(function), std::ref(*this), std::forward<Args>(args)...)

&& are for universal references, not r-values in your case

Upvotes: 0

Related Questions