Listing 3: Test program

// Listing 3 - test.cpp

#include <iostream>
#include <windows.h>    // for GetCurrentThreadId

#include "thread1.h"
#include "thread2.h"

using std::cout;
using std::cin;

// test class
class Foo
{
public:
    DWORD WINAPI test0()
    {
        cout << "test0:" << GetCurrentThreadId() << std::endl;
        return 0;
    }
    DWORD test1(char *param)
    {
        cout << "test1:" << GetCurrentThreadId();
        cout << " param=" << param << std::endl;
        return 0;
    }

    // test strongly typed parameters
    struct TestArg
    {
        long id;
        TestArg(long value) : id(value) {}
    };
    DWORD test2(const struct TestArg &args) const
    {
        cout << "test2:" << GetCurrentThreadId();
        cout << " param=" << args.id << std::endl;
        return 0;
    }
};


int main(int argc, char *argv[])
{
    cout << "main:" << GetCurrentThreadId() << std::endl;

    Foo f;

    // version from thread1.h
    MSVC::runInThread(f,&Foo::test0);

    // version from thread2.h

    // class requires explicit specification of template types
    ThreadableMember<Foo, DWORD (Foo::*)(char*), char*>
        m(f,&Foo::test1);

    m.run("alpha");

    // function template provides automatic detection of types
    runInThread(f,&Foo::test1, (char*)"bravo");

    // member can take strongly typed parameters
    runInThread(f,&Foo::test2, struct Foo::TestArg(99));

    char c;
    cin.get(c);

    return 0;
}