4

I try to pass a function object to a thread. I am confused when I found the copy constructor is called two times in the 'main' thread. Why not simply copy once instead of twice? The second copy is useless.

Code Snippet:

#include <iostream>
#include <thread>
using namespace std;

struct A
{
    A()
    {
        cout << "constructor      this=" << this << " thread_id=" << this_thread::get_id() << endl;
    }
    A(const A &other)
    {
        cout << "Copy constructor this=" << this << " thread_id=" << this_thread::get_id() << endl;
    }
    void operator()()
    {
        cout << "operator()       this=" << this << " thread_id=" << this_thread::get_id() << endl;
    }
    ~A()
    {
        cout << "destructor       this=" << this << " thread_id=" << this_thread::get_id() << endl;
    }
};

int main()
{
    A a;
    thread t(a);
    t.join();
    return 0;
}

The result is below:

constructor      this=0x7ffee91f5888 thread_id=0x7fff8b2a6340
Copy constructor this=0x7ffee91f5370 thread_id=0x7fff8b2a6340
Copy constructor this=0x7fb8de402870 thread_id=0x7fff8b2a6340
destructor       this=0x7ffee91f5370 thread_id=0x7fff8b2a6340
operator()       this=0x7fb8de402870 thread_id=0x700007c95000
destructor       this=0x7fb8de402870 thread_id=0x700007c95000
destructor       this=0x7ffee91f5888 thread_id=0x7fff8b2a6340
1201ProgramAlarm
  • 32,384
  • 7
  • 42
  • 56
  • 1
    `std::thread`s constructor takes it's arguments by value. If it then needs to forward this to some other function/object I don't see how it could not copy again. If you give your function object a move constructor you could get copy+move, or even move+move if you do `thread t(A{});` – super Apr 07 '18 at 05:07
  • Which compiler/version are you using? When I run this using Visual Studio 2017 (debug build), it only makes one copy. – 1201ProgramAlarm Apr 07 '18 at 20:52
  • I've closed this as a duplicate. The other question is about additional moves being done, but it's the same issue (your class has no move constructor, so it uses the copy constructor instead). With the upcoming GCC 10 release the redundant copy is gone. – Jonathan Wakely Feb 05 '20 at 14:09

0 Answers0