Portable C++98 thread class akin to std::thread I want a homegrown version of C++11's std::thread. My motivation is to avoid manual memory management of the arguments passed to the thread function. I'm restricted to C++98. I want better type safety than what's available in the POSIX and Win32 thread APIs.

Two notes:


I can't think of a way to avoid a heap allocation for the thunk argument. The thread instance could be deleted before the thunk has a chance to construct its arguments. I suppose I could wait on an event in the constructor signaled by thunk() once the thread is in a 'ready' state, but that seems horrible.
I'm not too concerned about exception safety as exceptions are disabled for most of this C++ codebase.




/* There is a portable thread implementation in C available already */
int portable_thread_create(portable_thread_t *)
{
    pthread_create() **OR**
    _beginthreadex()
}

#define PORTABLE_THREAD_FUNC_DECL void *
#define PORTABLE_THREAD_FUNC_DECL unsigned int __cdecl **OR**

void portable_thread_join(portable_thread_t)
{
    pthread_join() **OR**
    WaitForSingleObject()
}

template &lt; typename TArg0 &gt;
class thread
{
public:
    typedef void (*function_t)(TArg0);
    thread(function_t func, TArg0 arg0)
        : m_func(func)
    {
        m_arg0 = new TThunkArg(this, arg0);
        if (0 != portable_thread_create(&amp;m_thread, thunk, m_arg0))
        {
            delete m_arg0;
            throw new std::runtime_error("Could not create a thread");
        }
    }

    void join()
    {
        portable_thread_join(m_thread);
    }

private:
    struct TThunkArg
    {
        thread&lt;TArg0&gt; *Self;
        TArg0 Arg0;
        TThunkArg(thread&lt;TArg0&gt; *self, TArg0 arg0)
            : Self(self)
            , Arg0(arg0)
        {}
    };
    static PORTABLE_THREAD_FUNC_DECL thunk(void *unsafe_args)
    {
        TThunkArg *args = reinterpret_cast&lt;TThunkArg*&gt;(unsafe_args);
        try
        {
            args-&gt;Self-&gt;m_func(args-&gt;Arg0);
        }
        catch(...)
        {
            delete args;
            throw;
        }

        delete args;
        return 0;
    }
    portable_thread_t m_thread;
    function_t m_func;
    TThunkArg *m_arg0;
};
You can put the unsafe_args in a auto_ptr so RAII can delete them safely. This is safe because you will not be copying it around.

static PORTABLE_THREAD_FUNC_DECL thunk(void *unsafe_args)
{
    std::auto_ptr&lt;TThunkArg&gt; args(reinterpret_cast&lt;TThunkArg*&gt;(unsafe_args));
    args-&gt;Self-&gt;m_func(args-&gt;Arg0);

    return 0;
}


Also don't worry about having to new the args; you are creating a new thread, this is much more expensive than a quick malloc call.