1

In C++11, I want to create objects of classes Foo and Alpha (foo and alpha, respectively). I then want to create a thread which calls a function of alpha, passing foo as the argument. Whilst this thread runs, I then want to be able to modify foo.

Here's my code so far:

#include <thread>
#include <iostream>

class Foo
{
public:
    int x;
    void Bar()
    {
        std::cout << x << std::endl;
    }
};

class Alpha
{
public:
    void Beta(Foo& foo)
    {
        while (true)
        {
            foo.Bar();
        }
    }
};

int main()
{
    Foo foo;
    foo.x = 5;
    Alpha alpha;
    std::thread beta_thread(&Alpha::Beta, alpha, foo);
    beta_thread.join();

    while (true)
    {
        foo.x++;
    }

    return 0;
}

However, this gives me a compile error:

/usr/include/c++/4.8/functional:1697: error: no type named 'type' in 'class std::result_of<std::_Mem_fn<void (Alpha::*)(Foo&)>(Alpha, Foo)>'
       typedef typename result_of<_Callable(_Args...)>::type result_type;
                                                             ^

If I pass foo by value rather than reference (void Beta(Foo foo)), then it compiles ok. However, I believe that I need to pass by reference so that when I modify foo in the main loop, it will change the same instance that I passed to Beta.

Any help?

Karnivaurus
  • 22,823
  • 57
  • 147
  • 247

1 Answers1

3

When you pass objects to the thread constructor, they are taken by value. If you want to pass something by reference, you have to say std::ref(foo).

The reason the default is to take the arguments by value instead of with, say, perfect forwarding, is because the thread's lifetime will often not be scope limited, and the designers did not want to make it quite that easy to accidentally create dangling references when local objects are used as arguments.

bames53
  • 86,085
  • 15
  • 179
  • 244