Преобразование std :: thread, на которое указывает указатель void, на объект std :: thread вместо указателя на объект - PullRequest
0 голосов
/ 06 августа 2020

Я искал упражнение, которое я сделал, а именно класс «менеджер потоков», который управляет потоками (на самом деле? Lol), сохраняя их внутри массива «typedef void * HANDLE;» объявлен внутри struct GROUP.

Итак, я уже заставил его работать, но я увидел, что конвертирую "HANDLE", поэтому "void *" путем преобразования "reinterpret_cast" в "std :: thread *" .

После того, как я увидел это, я забеспокоился: как и можно преобразовать его напрямую в объект std :: thread?

Я сделал этот код, например:

#include <iostream>
#include <thread>

typedef void *HANDLE;

class thread_obj {
    public:
        void operator()(int x){
            for(int i = 0x0; i < x; i++){
                std::cout << "i = " << i << std::endl;
            }
        }
};

int main(){

    std::thread thr(thread_obj(), 0x3);
    HANDLE test = &thr;

    std::thread *p_thr = reinterpret_cast<std::thread*>(test);

    p_thr->join();

    return 0x0;
}

Это исходный код.

Если вместо этого я сделаю:

std::thread p_thr = reinterpret_cast<std::thread&>(test);

или:

std::thread p_thr = *reinterpret_cast<std::thread*>(test);

или:

std::thread *temp = reinterpret_cast<std::thread*>(test);
std::thread p_thr = *temp;

I всегда получать:

ошибка: использование удаленной функции 'std :: thread :: thread (std :: thread &)'

В строке «reinterpret_cast» для первой и во втором случае, и в следующей строке присваивания для третьего.

Теперь я полагаю, что проблема связана с вызываемым конструктором копирования. Я немного поискал, открыл класс потока и нашел его:

thread(thread&) = delete;

Итак: / немного поискав Я нашел только решение, в котором вы переопределяете конструктор копирования. В этом случае я думаю, что решением может быть создание суперкласса и повторное объявление этого удаленного конструктора, верно? Но это пустая трата времени: /

Итак, есть ли способ преобразовать этот "void *" в объект "std :: thread", снова в объект "std :: thread"? Если да или нет, не могли бы вы объяснить мне подробно, пожалуйста?

Большое спасибо, хорошего дня и кодирования: D

1 Ответ

5 голосов
/ 06 августа 2020

Что вам действительно нужно, так это

std::thread& ref_thr = *reinterpret_cast<std::thread*>(test);
//         ^ declare a reference to a std::thread

, а затем вы можете использовать ref_thr точно так же, как и обычный объект.

Как вы обнаружили, конструктор копирования для std::thread удаляется, поэтому, если вы действительно хотите создать объект потока из test, вам нужно переместить приведенный объект в new_thr, например

std::thread new_thr = std::move(*reinterpret_cast<std::thread*>(test));

, но это означает, что указатель объекта to by test больше нельзя использовать, так как он был перемещен в new_thr. Вот почему вы хотите использовать ссылку, если только вы не хотите ее переместить.

...