1

Using Boost 1.43 threads, the following is compilable:

void MyClass::threadFn(...) { ... }
void MyClass::doFn(...) {
    ...
    boost::thread(&MyClass::threadFn, this, ...);
}

But the following is not compilable:

void MyClass:doFn(...) {
    ...
    struct MyStruct {
        MyStruct(...) { ... };
    }

    boost::thread(&MyStruct, ...);
}

This yields 'MyClass::doFn::MyStruct': illegal use of this type as an expression. Note that I am not trying to pass a pointer to an instance of MyStruct; I am trying to pass the type itself, as I would a function pointer, so that boost::thread will invoke the constructor of the type.

According to The Boost 1.43 Threads Spec:

A new thread is launched by passing an object of a callable type

So how do I pass the address of the struct type to the boost::thread function (AFAIK this would also apply to boost::bind)?

Further reading on how to accomplish this with functions

Community
  • 1
  • 1
taz
  • 1,506
  • 3
  • 15
  • 26
  • 2
    MyStruct is not a *callable* type. You need to define a function which operates upon a MyStruct and then use that function to instantiate the thread instead. – Max DeLiso Sep 13 '12 at 00:07
  • Also, you're missing a semicolon, and `MyStruct` isn't even in scope at the desired line. – Kerrek SB Sep 13 '12 at 00:09
  • @user931794: How do I do that? I can't instantiate the MyStruct in the function, because the operations performed by MyStruct need to be started in a new thread. – taz Sep 13 '12 at 00:09
  • @KerrekSB: Edited to include the semicolon; how is `MyStruct` not in scope at the desired line? The compiler thinks it is and recognizes it as an invalid type. (The actual code is far more complex than this - typos in this example are not actually from my code.) – taz Sep 13 '12 at 00:11
  • @taz: Oh, sorry, that's true - it is in scope, but it's a local class. In C++03, those can't be template arguments. – Kerrek SB Sep 13 '12 at 00:15
  • (Also, please don't type examples. Paste them from your minimal, self-contained, compilable code on your machine.) – Kerrek SB Sep 13 '12 at 00:16
  • @KerrekSB I would normally make a SSCE but I cannot afford to take time out for it. Is C++03 the standard before C++11? What does Visual Studio 10 use? (Googling right now but haven't found yet) – taz Sep 13 '12 at 00:22
  • @taz: VS10 has partial support for C++11; but then you should also be using `std::thread` in preference over Boost. – Kerrek SB Sep 13 '12 at 00:43
  • @KerrekSB: I'm not familiar with preferring `std::thread` over Boost. Does boost require C++11 implementation? I thought Boost was implemented into C++11. – taz Sep 13 '12 at 01:23
  • @user931794's comment says it all. user931794: You should make it an answer (and perhaps explain what _callable_ means, just to be sure). – jogojapan Sep 13 '12 at 01:33
  • @taz: With C++11, you don't need Boost for threads. You can simply `#include ` and use `std::thread`. It has the same interface. – Kerrek SB Sep 13 '12 at 05:32
  • @KerrekSB I was under the impression that a lot of boost was incorporated into C++11. However my platform is Visual Studio 2010, which does not use C++11 AFAIK. – taz Sep 13 '12 at 14:18

3 Answers3

1

I'm not really sure what the purpose is, but the following would call MyStruct():

boost::thread(boost::bind(boost::value_factory<MyStruct>()));

You can pass arguments also, for example with MyStruct(int i, int j):

boost::thread(boost::bind(boost::value_factory<MyStruct>(), 1, 2));
Jesse Good
  • 50,901
  • 14
  • 124
  • 166
1

MyStruct is not a callable type. You need to define a function which operates upon a MyStruct and then use that function to instantiate the thread instead.

A thread is an execution context, and to instantiate one you need a set of instructions for it to execute.

In Java, we see this in the form of a Runnable, which is used to instantiate a Thread, which can then be start()ed.

In C/C++ with Boost, you must use a function pointer.

The term "callable type" translates roughly into "type which is exchangeable with function pointer."

If you want to operate on an arbitrary struct, as in your example, MyStruct, you first must define a set of instructions ( a function ) which operates on that type.

Once you know the set of instructions, you can pass a pointer to that function to intantiate a thread, and then run that thread with arbitrary instances of MyStruct.

Code follows:

struct MyStruct {
        MyStruct(...) { ... }
    };

int frobnicateMyStruct( const MyStruct& msr ) {

    /* some operations on msr */

    return 0;
}    

void foo() {

    MyStruct myStructInstance;
    boost::thread(&frobnicateMyStruct, myStructInstance);

    /* ... */

    return;
}
Jesse Good
  • 50,901
  • 14
  • 124
  • 166
Max DeLiso
  • 1,213
  • 11
  • 23
  • thanks for those fixes. I like having the autos in my code to remind me about their storage class but I can see why you took them out. – Max DeLiso Sep 13 '12 at 02:33
0

Instead of:

boost::thread(&MyStruct, ...);

Invoke an instance:

boost::thread(MyStruct(), ...);
Drew Dormann
  • 59,987
  • 13
  • 123
  • 180
  • This would still require `MyStruct` to be callable. i.e. `(MyStruct())()` – Jesse Good Sep 13 '12 at 01:18
  • `Note that I am not trying to pass a pointer to an instance of MyStruct; I am trying to pass the type itself, as I would a function pointer, so that boost::thread will invoke the constructor of the type.` – taz Sep 13 '12 at 01:24
  • 1
    @taz - a function pointer is not a type. You can't pass a type to `boost::thread`. You can write a function that constructs a `MyStruct` object, and pass that function. – Pete Becker Sep 13 '12 at 01:25