-1

Is this illegal? How do I hide this global thread instance with private? It seems to work without const but I would still like to const it just for peace of mind.

struct AbstractImage {
private:
    static void LoadImages();
    static const std::thread ImageLoader;
};
...
const std::thread AbstractImage::ImageLoader( AbstractImage::LoadImages );

void AbstractImage::LoadImages() {
    ImageLoader.detach();
}
'void std::thread::detach(void)': cannot convert 'this' pointer from 'const std::thread' to 'std::thread &'
Anton Duzenko
  • 2,366
  • 1
  • 21
  • 26
  • `detach` needs to mutate the state of the thread object. As you can see from the fact that is not a const method. So no you cannot detach on a const thread. "I would still like to const it just for peace of mind." What peace of mind? If you need detach you need it to be mutable. – bolov Jul 06 '20 at 18:17
  • I would be happy to not detach it, but otherwise it pops up a silly assert failed dialog at program exit. – Anton Duzenko Jul 06 '20 at 19:08
  • Why do you need a global `std::thread` object at all? Why not just call a function at startup, and have that function use a local `std::thread` that it detaches before exiting? – Remy Lebeau Jul 06 '20 at 20:41
  • 1
    Re. `"...it pops up a silly assert failed dialog at program exit"`, that's because you're (probably) not [joining](https://en.cppreference.com/w/cpp/thread/thread/join) it before its destructor is invoked. – G.M. Jul 07 '20 at 06:55
  • @RemyLebeau I use a private member so that it can call a private struct function – Anton Duzenko Jul 07 '20 at 07:07
  • @G.M. right, but how to work around it? – Anton Duzenko Jul 07 '20 at 07:08
  • @AntonDuzenko you don't need a `static std::thread` object for that. A local `std::thread` object inside a `static` method will work. If needed, you can make `std::thread` a `friend` of `AbstractImage`. – Remy Lebeau Jul 07 '20 at 16:34
  • @RemyLebeau And how do I invoke that static method? From main()? It's a thread that is supposed to call the method, not vice versa – Anton Duzenko Jul 07 '20 at 16:39
  • @AntonDuzenko the method to start the thread can be called in the constructor of a global object (you don't need to make the `std::thread` itself global). Or, you can use `#pragma startup` or equivalent, if your compiler supports that. – Remy Lebeau Jul 07 '20 at 16:42
  • @RemyLebeau I don't have a dedicated instance of AbstractImage (and it's abstract BTW). Which is why the static thread. Not excited about pragma startup either. – Anton Duzenko Jul 07 '20 at 16:46
  • @AntonDuzenko you don't need a dedicated instance of `AbstractImage`. I have written up an answer to show this. – Remy Lebeau Jul 07 '20 at 17:30

1 Answers1

0

You can't call detach() on a const std::thread object, since detach() needs to modify the state of the std::thread.

In this case, I would suggest not using a static std::thread object at all. Especially since it is a one-time-use thread, so the std::thread object doesn't need to hang around once the thread starts running. Use a local std::thread variable inside of another function or static method, and then you can call that at startup as needed, eg:

struct AbstractImage
{
private:
    static void LoadImages();

    struct LoadImagesStarter
    {
        LoadImagesStarter()
        {
            std::thread(AbstractImage::LoadImages).detach();
        }
    };

    static const LoadImagesStarter ImageLoader;
};
...

const AbstractImage::LoadImagesStarter AbstractImage::ImageLoader;

void AbstractImage::LoadImages()
{
    ...
}

Live Demo

Alternatively:

struct AbstractImage
{
private:
    static void LoadImages();

    friend void LoadImagesStarter();
};
//...

void AbstractImage::LoadImages()
{
    ...
}

__attribute__((constructor)) void LoadImagesStarter()
{
    std::thread(AbstractImage::LoadImages).detach();
}

/* or, if your compiler supports this:
void LoadImagesStarter()
{
    std::thread(AbstractImage::LoadImages).detach();
}
#pragma startup LoadImagesStarter 100
*/

Live Demo

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770