参考 std::thread 参数

问题描述

我有两个功能

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

我可以制作

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

但是我不能创建 std::thread t2(g,x)在这种情况下我需要 make std::ref(x) 而不仅仅是 x,为什么需要?

为什么可以在没有 t1 的情况下创建 std::cref

解决方法

如果没有 f(),您的 std::cref() 函数将无法正常工作。

虽然 f() 不打算改变 x 后面的值,但这并不意味着这个引用后面的值不能在其他地方改变。

在这个例子中,没有std::cref(),原始int的副本被放入线程堆栈,x引用这个副本;我们看到 11

另一方面,对于 std::cref()x 仍然引用原始;我们看到 12

/**
  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;
}