The Author Online Book Forums are Moving

The Author Online Book Forums will soon redirect to Manning's liveBook and liveVideo. All book forum content will migrate to liveBook's discussion forum and all video forum content will migrate to liveVideo. Log in to liveBook or liveVideo with your Manning credentials to join the discussion!

Thank you for your engagement in the AoF over the years! We look forward to offering you a more enhanced forum experience.

johannkokos (4) [Avatar] Offline
#1
In section 2.1.1,


In this case, the supplied function object is copied into the storage belonging to the newly created thread of execution and invoked from there.


I find default constructor, copy constructor and move constructor are called in this example. And the function object in the new thread is created by move constructor in the last step.

#include <iostream>
#include <string>
#include <thread>

class C {
  std::string s;
public:
  void operator() () const {
    std::cout << "function object in new thread is created by: " + s << std::endl;
  }
  C() = default;
  C(const C& another) {
    s = "copy constructor";
  }
  C(C&& another) {
    s = "move constructor";
  }
};

int main() {
  C c;
  std::thread t{c};
  t.join();
  return 0;
}


It shows,
function object in new thread is created by: move constructor
georger.araujo (6) [Avatar] Offline
#2
It depends. If the supplied callable object is an rvalue, it is moved into internal storage. If it is an lvalue, it is copied. Section A.1.2 of the first edition provides a good explanation of how the std::thread constructor does it.

Also, when I run a slightly expanded version of your code (see below) on MSVC2015 32-bit, this is the output I get:

function object in new thread is created by: copy constructor
function object in new thread is created by: move constructor


#include <iostream>
#include <string>
#include <thread>

class C {
  std::string s;
public:
  void operator() () const {
    std::cout << "function object in new thread is created by: " + s << std::endl;
  }
  C() = default;
  C(const C& another) {
    s = "copy constructor";
  }
  C(C&& another) {
    s = "move constructor";
  }
};

int main() {
  C c;
  std::thread t{c};
  t.join();

  std::thread t2{C{}};
  t2.join();

  return 0;
}
johannkokos (4) [Avatar] Offline
#3
That's interesting to hear. I am compiling your modified code on gcc-7.3 and clang-5.0,

g++ -std=c++17 -Wall -Wextra -pedantic -pthread -O3 main.cc


The output is (same for gcc and clang),

function object in new thread is created by: move constructor
function object in new thread is created by: move constructor


Edit: both copy and move constructor are called in the first case, and two move constructors are called in the second case.
georger.araujo (6) [Avatar] Offline
#4
If you want to try it on MSVC but don't have a Windows machine handy, you can test it online at http://rextester.com/l/cpp_online_compiler_visual
johannkokos (4) [Avatar] Offline
#5
Thanks for letting me know. The VS online compiler is great.