提问人:Артём Гаркавый 提问时间:2/23/2021 最后编辑:463035818_is_not_an_aiАртём Гаркавый 更新时间:2/23/2021 访问量:543
在 std::thread 参数处引用
Reference at std::thread parameters
问:
我有两个功能
void f(const int &x) {}
void g(int& x) {}
我能做到
int x = 0;
std::thread t1(f, x);
但是我不能创造,在这种情况下我需要制作而不仅仅是,为什么有必要呢?std::thread t2(g, x)
std::ref(x)
x
为什么可以在没有?t1
std::cref
答:
2赞
prog-fh
2/23/2021
#1
如果没有 ,您的函数将无法按预期工作。f()
std::cref()
虽然无意改变后面的值,但这并不意味着这个引用后面的值不能在其他地方发生变异。f()
x
在此示例中,没有原始副本的副本被放入线程堆栈中,并引用此副本;我们看到 和 .std::cref()
int
x
1
1
另一方面,with ,仍然引用原文;我们看到 和 .std::cref()
x
1
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;
}
评论
0赞
Артём Гаркавый
2/23/2021
谢谢!可惜C++通过隐身会复制对象。顺便说一句,为什么当我将 std::cref 更改为 std::ref 时,此代码有效?行为应该是一样的吗?
1赞
prog-fh
2/23/2021
@АртёмГаркавый 是一个引用,因此提供可变的引用包装器不会造成伤害。另一方面,提供一个 const-reference 包装器,其中需要对可变对象的引用(在您的问题中)会让编译器抱怨。x
const
g()
0赞
Kuba hasn't forgotten Monica
2/23/2021
@АртёмГаркавый 可惜隐身C++会复制对象 “隐身”和“对C++的基本语义理解不够”之间有一条细线。这些语义并不是不言自明的,尽管它们确实出现在语言的设计过程中,并且通常是一种特殊的方式,否则“简单”的东西就会被破坏或变得不那么明显。这就是C++经验的意义:这种理解是有效使用语言所固有的。对于相对新手来说,很多东西看起来都是隐秘的,无论编程语言如何。
评论
std::thread
将参数复制到函数中。 将对象包装在授予引用语义的 a 中,因此副本引用原始对象。std::ref
std::reference_wrapper
t1
std::cref
std::thread t1(f, x)
f
x
int
x
std::cref