Aperion
Aperion

Reputation: 283

Thread move in C++11

I meet some problem when testing examples in C++ concurrency in Action.

/***
Scoped_thread
Help explain the move semantics of Scoped_guard
@c++ Concurrency in Action
***/
#include <thread>
#include <iostream>
using namespace std;
class Scoped_thread
{
  std::thread t;
public:
  Scoped_thread(std::thread _t):
    t(std::move(_t))
    {
      cout << "Success?" << endl;
      if (!t.joinable())
        throw std::logic_error("No thread");
    }
  ~Scoped_thread()
  {
    t.join();
  }
  Scoped_thread(Scoped_thread const&) = delete;
  Scoped_thread& operator=(Scoped_thread const&) = delete;
};

struct func
{
  int& i;
  func(int& i):i(i) {}
  void operator()()
  {
    for (unsigned j = 0; j < 1000000; j++)
    {
      cout << j << endl;
    }
  }
};

int main()
{
  int some_local_state = 1;
  func myfunc(some_local_state);
  Scoped_thread t2(std::thread(myfunc));
  for (unsigned j = 0; j < 1000; j++)
  {
    cout << "Main thread " << j << endl;
  }
}

When printing out, only "Main Thread" comes out. I've found the constructor didn't start. Does that indicates some problem using thread move semantics? My working environment is Ubuntu 16.04, and the compile command is 'g++ -std=c++11 -Wall -pthread file.cpp'

Upvotes: 3

Views: 163

Answers (1)

Joseph Artsimovich
Joseph Artsimovich

Reputation: 1519

Scoped_thread t2(std::thread(myfunc));

Here we have a slightly non-conventional case of most vexing parse. The thing is: the following function forward declarations are equivalent:

void f(int arg);
void f(int (arg));

Therefore, Scoped_thread t2(std::thread(myfunc)); gets parsed as a forward declaration of function t2 that returns Scoped_thread and takes std::thread myfunc as an argument.

Two solution is:

Scoped_thread t2{std::thread(myfunc)};

Upvotes: 1

Related Questions