Listing 1: The technique

#include <pthread.h>

struct Thread {
    Thread (const pthread_t &pt) :  pt (pt) {};
    void join () { pthread_join (pt, 0); };    
  private:
    pthread_t pt;
};


struct FunData {
    typedef void * (*ThreadEntryPoint) (void *);
    FunData (const ThreadEntryPoint tep) 
                           : thread_entry_point (tep) {};
    ThreadEntryPoint thread_entry_point;
};


template <typename Arg1>
class FunWrapper1 {
    struct Data : public FunData {
      typedef void (*FunPtr) (Arg1);
      Data (FunPtr fun_ptr, Arg1   arg1)
              : FunData (&Data::thread_entry_point),
                fun_ptr (fun_ptr),
                arg1 (arg1)  {};
        private:
      FunPtr fun_ptr;
      Arg1   arg1;
      static void * thread_entry_point (void *arg);
    };
    
  public:
    typedef void (*FunPtr) (Arg1);

    FunWrapper1 (FunPtr fun_ptr) : fun_ptr(fun_ptr) {};

    Thread operator() (Arg1 arg1) {
      Data data(fun_ptr, arg1);
      return do_spawn (data);
    };
    
  private:
    FunPtr fun_ptr;
};


template <typename Arg1>
void * FunWrapper1<Arg1>::Data::thread_entry_point (void *arg) {
  const Data *data = reinterpret_cast<const Data*> (arg);
  (*data->fun_ptr)(data->arg1);
  return 0;
}

    
Thread do_spawn (const FunData &data) {
  pthread_t pt;
  pthread_create (&pt, 0, *data.thread_entry_point, 
                  (void *)&data);
  return pt;
}


template <typename Arg1>
FunWrapper1<Arg1> spawn (void (*fun_ptr)(Arg1)) {
  return FunWrapper1<Arg1>(fun_ptr);
}
— End of Listing —