-2

I'm trying to create a "guarded_thread", but I receive an error 'operator=' is a private member of 'std::__1::thread'. Here is my code:

struct guarded_thread : std::thread{
    using std::thread::thread;
    using std::thread::operator=;
    ~guarded_thread(){if(joinable())join();}
};

A function did the work, but I want to know how to create it the other way

void Guarded_thread(std::thread &Thread){
    if (Thread.joinable()) {
        Thread.join();
    }
}
463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185
N.T.
  • 1
  • 1
  • 1
    Please show a [mre] and explain what your code is supposed to do. Isn't the error fairly self explanatory? You're trying to use the assignment operator which is private on `std::thread` – Alan Birtles May 08 '21 at 10:35
  • note that C++20 has `std::jthread` and that (publicly) inheriting from std types isnt always the best idea. – 463035818_is_not_an_ai May 08 '21 at 10:40
  • `std::thread` cannot be copied, and so can't any classes inheriting from it. But you could have a simple `std::thread` member variable for your class, instead of inheriting. – πάντα ῥεῖ May 08 '21 at 10:42
  • the code doesn't also take in account that thread can be running indefinitely and be running when destructor is called. jthread is requested to stop from destructor, which is a feature of jthread. – Swift - Friday Pie May 08 '21 at 10:56

1 Answers1

1

std::threads destructor is not virtual. Hence, you won't get to use your guarded_thread polymorphically and there is little benefit of inheritance compared to making the thread a member. std::thread cannot be copied, thats basically what the error says, so guarded_thread cannot be copied as well. Though, it can be moved:

#include <thread>
#include <iostream>

struct guarded_thread {
    std::thread t;
    ~guarded_thread() {
        if(t.joinable()) {
            t.join();
        }
    }
};

void foo(guarded_thread&& t) {}

int main() {
    foo(guarded_thread{ std::thread{ [](){ std::cout << "hello world"; }}});
}

Live Demo

PS: std::thread not joining in its destructor was a surprise for many, and maybe also driven by that C++20 introduced std::jthread. As pointed out in a comment by Swift, std::jthreads destructor also request_stop()s the thread before joining it, while guarded_thread blocks forever when the thread runs infinitely.

463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185