Reference at std::thread parameters

658 Views Asked by At

I have two functions

void f(const int &x) {}
void g(int& x) {}

I can make

int x = 0;
std::thread t1(f, x);

But I can't create std::thread t2(g, x), in this case i need make std::ref(x) instead of just x, why is it necessary?

And why it possible to create t1 without std::cref?

1

There are 1 best solutions below

3
On BEST ANSWER

Your f() function does not work as you expect without std::cref().

Although f() does not intent to change the value behind x, it does not mean that the value behind this reference cannot be mutated elsewhere.

In this example, without std::cref() a copy of the original int is put in the thread stack, and x references this copy; we see 1 and 1.

On the other hand, with std::cref(), x still references the original; we see 1 and 2.

/**
  g++ -std=c++17 -o prog_cpp prog_cpp.cpp \
      -pedantic -Wall -Wextra -Wconversion -Wno-sign-conversion \
      -g -O0 -UNDEBUG -fsanitize=address,undefined -pthread
**/

#include <iostream>
#include <thread>

using namespace std::chrono_literals;
void
f(const int &x)
{
  std::cout << "x=" << x << '\n';
  std::this_thread::sleep_for(1000ms);
  std::cout << "x=" << x << '\n';
}

int
main()
{
  int i=1;
  // std::thread th{f, i}; // copy to thread stack
  std::thread th{f, std::cref(i)}; // reference the original i
  std::this_thread::sleep_for(500ms);
  i+=1;
  th.join();
  return 0;
}