3

I am using g++ 4.7 with the c++11 flag. In this demo:

#include <iostream>
#include <thread>

class do_work
{
public:
   void operator()()
   {
     std::cout << "Doing work..." << std::endl;
   }
};

void foo()
{

}

int main()
{
  // Does not work
  std::thread t(do_work);
  t.join(); // error: request for member ‘join’ in ‘t’, which is of non-class type ‘std::thread(do_work)’

  // Works
  std::thread t2(foo);
  t2.join();

  return 0;
}

I can successfully call join() on a thread that was created with a function as its constructor argument, but I cannot call join() (see the error inline) on a thread that was created with a functor as its constructor argument. Can anyone explain this?

ildjarn
  • 62,044
  • 9
  • 127
  • 211
David Doria
  • 9,873
  • 17
  • 85
  • 147
  • possible duplicate of [C++: bizarre occurrence of "Request for member X of Y which is of non-class type Z"](http://stackoverflow.com/questions/11138543/c-bizarre-occurrence-of-request-for-member-x-of-y-which-is-of-non-class-type) – ecatmur Sep 21 '12 at 17:30

1 Answers1

12

You've declared t as a function taking do_work and returning std::thread.

You probably want to write

do_work worker;
std::thread t{worker};

or

std::thread t{do_work{}};

or

std::thread t((do_work()));

Note that

std::thread t(do_work());

won't work; it's vexingly parsed as declaring a function t taking a function that takes no arguments and returns do_work, and returning std::thread. Wrapping the do_work temporary with parentheses or using uniform initializer syntax (at any point) will fix it.

This is a good reason to get into the habit of using uniform initializer syntax wherever possible; if you'd written

std::thread t{do_work};  // incorrect

then compilation would have failed on that line instead of the join.

Community
  • 1
  • 1
ecatmur
  • 152,476
  • 27
  • 293
  • 366
  • 1
    Ah, excellent. I'm glad my silly mistake led me to learn a real thing instead of just being a "doh!" moment :) – David Doria Sep 21 '12 at 17:34