有人可以举一个简单的例子来演示功能std::ref
吗?我的意思是一个示例,其中仅在无法解释时才使用其他一些构造(如元组或数据类型模板)的例子std::ref
。
我在std::ref
这里和这里发现了两个问题。但是在第一个中,它涉及编译器中的错误;在第二个中,std::ref
它不包含使用示例,std::ref
它们涉及元组和数据类型模板,这使得对这些示例的理解变得复杂。
Answers:
您应该考虑使用std::ref
以下函数:
std::bind
或的构造函数std::thread
。std::ref
是行为类似于引用的值类型。
此示例可证明使用std::ref
。
#include <iostream>
#include <functional>
void increment( int &x )
{
++x;
}
int main()
{
int i = 0;
// Here, we bind increment to (a copy of) i...
std::bind( increment, i ) ();
// ^^ (...and invoke the resulting function object)
// i is still 0, because the copy was incremented.
std::cout << i << std::endl;
// Now, we bind increment to std::ref(i)
std::bind( increment, std::ref(i) ) ();
// i has now been incremented.
std::cout << i << std::endl;
}
输出:
0
1
std::ref
是,它是可重新绑定的,这与常规参考不同,传统参考如果将其馈入模板函数可能会很重要。有关示例,请参见stackoverflow.com/questions/37101301/…。
您可能需要std :: ref的另一个地方是将对象传递给线程时,您希望每个线程在单个对象而不是对象的副本上进行操作。
int main(){
BoundedBuffer buffer(200);
std::thread c1(consumer, 0, std::ref(buffer));
std::thread c2(consumer, 1, std::ref(buffer));
std::thread c3(consumer, 2, std::ref(buffer));
std::thread p1(producer, 0, std::ref(buffer));
std::thread p2(producer, 1, std::ref(buffer));
c1.join();
c2.join();
c3.join();
p1.join();
p2.join();
return 0; }
您希望在各个线程中运行的各种功能共享一个缓冲区对象。这个例子是从这个出色的教程(C ++ 11并发教程-第3部分:高级锁定和条件变量(Baptiste Wicht) )中窃取的(希望我正确地进行了归因)
std::ref
这里使用的原因是,构造函数thread
需要一个参数类型std::reference_wrapper
//生产者消费者问题
#include <iostream>
#include <thread>
#include <mutex>
#include <deque>
#include <condition_variable>
using namespace std;
class Buffer {
std::mutex m;
std::condition_variable cv;
std::deque<int> queue;
const unsigned long size = 1000;
public:
void addNum(int num) {
std::unique_lock<std::mutex> lock(m);
cv.wait(lock, [this]() { return queue.size() <= size; });
queue.push_back(num);
cout << "Pushed " << num << endl;
lock.unlock();
cv.notify_all();
}
int removeNum() {
std::unique_lock<std::mutex> lock(m);
cv.wait(lock, [this]() { return queue.size()>0; });
int num = queue.back();
queue.pop_back();
cout << "Poped " << num << endl;
lock.unlock();
cv.notify_all();
return num;
}
};
void producer(int val, Buffer& buf) {
for(int i=0; i<val; ++i){
buf.addNum(i);
}
}
void consumer(int val, Buffer& buf){
for(int i=0; i<val; ++i){
buf.removeNum();
}
}
int main() {
Buffer b;
std::thread t1(producer, 1000, std::ref(b));
std::thread t2(consumer, 1000, std::ref(b));
t1.join();
t2.join();
return 0;
}
在主Buffer
对象中使用std :: ref的另一种用法,同时在生产者和使用者中传递对象作为引用。如果std::ref
不使用,则此代码将无法编译。