0

I have a class Handler:

class Handler {
private:
    std::mutex _mutex_list[4];
    std:list<Person*> _waiting_list[4];
    std::thread __runner_t;
public:
    virtual void start();
};

I am trying to start the handler in a new thread:

Handler* handler = new Handler();
std::thread(&Handler::start, handler);

The problem is that apparently std::thread needs the class's transfer constructor, which I am unable to define as default because std::mutex can't be copied.

I defined a custom copy constructor which copies only the list but re-initializes the mutex array and thread.

Here it is:

Handler(const Handler& other) :
 _mutex_list(), _waiting_list(other._waiting_list), _runner_t() {};

Doesn't work of course because the compiler asks for a transfer constructor.

I am not sure how to achieve the same for a transfer.

Is it a correct solution ? Is there a better solution ?

Help is appreciated.

  • 1
    Can you give us a [mcve]? `Handler* handler = new Handler(); std::thread(&Handler::start, handler);` should work since you aren't copy the object, just a pointer to it. – NathanOliver Feb 12 '19 at 19:49
  • 2
    This doesn't address the question, but names that contain two consecutive underscores (`__runner_t`) and names that begin with an underscore followed by a capital letter are reserved for use by the implementation. Don't use them in your code. – Pete Becker Feb 12 '19 at 19:51
  • The answer for this question is here: https://stackoverflow.com/a/29988626/576911 – Howard Hinnant Feb 12 '19 at 20:01
  • Thanks for all replies, It finally resolved itself when trying to do the Minimal, Complete, and Verifiable example. It had a logic error where I was passing the object itself instead of the pointer (declared and defined in another file). –  Feb 12 '19 at 20:10

1 Answers1

1

There is no transfer constructor, there is move constructor. Your code has a logical issue - you are creating a thread and you are copying your object into it, but this object owns the thread, which is just wrong.

I'd say, if you have an object which owns thread, running this thread should be it's own function, like:

class Handler {
    ...
    void start() {
        __runner_t = std::thread(&thread_func, this);
    }
};

The technical compilation errors you are having, while solvable, highlight the logical issues.

SergeyA
  • 61,605
  • 5
  • 78
  • 137
  • Thanks for the reply, it's been fixed already like I said in the above comment. The thread object in Handler isn't the calling thread but another one that the handler starts on demand. –  Feb 12 '19 at 20:12
  • @SergeyA Doesn't your `Handler::start()` need to call `detach()` on the `std::thread` it creates? `std::thread(&thread_func, this).detach()` – Remy Lebeau Feb 12 '19 at 21:20
  • @RemyLebeau I meant to have the result saved in `__runner_t`, let me edit to that effect. Without this yes, it would be immediate abort. – SergeyA Feb 12 '19 at 21:24