对于"std::ref"来说,"Hello, World!"的例子是什么?
What would be a "Hello, World!" example for "std::ref"?
谁能举一个简单的例子来说明std::ref
的功能?我的意思是,只有在无法解释std::ref
的情况下,才使用其他结构(如元组或数据类型模板)的例子。
我在这里和这里发现了两个关于std::ref
的问题。但在第一个,它是关于一个编译器的错误,在第二个,使用std::ref
的例子不包含std::ref
,他们涉及元组和数据类型模板,使理解这些例子很复杂。
你应该考虑使用std::ref
当一个函数:
- 接受模板参数的值
- 复制/移动模板参数,如
std::bind
或std::thread
的构造函数。
std::ref
创建了一个可复制的值类型,其行为类似于引用。
这个例子演示了std::ref
的用法。
#include <iostream>
#include <functional>
#include <thread>
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;
// The same applies for std::thread
std::thread( increment, std::ref(i) ).join();
std::cout << i << std::endl;
}
输出:0
1
2
void PrintNumber(int i) {...}
int n = 4;
std::function<void()> print1 = std::bind(&PrintNumber, n);
std::function<void()> print2 = std::bind(&PrintNumber, std::ref(n));
n = 5;
print1(); //prints 4
print2(); //prints 5
std::ref
主要用于在使用std::bind
时封装引用(当然也有其他用途)。
另一个可能需要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部分:高级锁定和条件变量)中偷来的。
//生产者消费者问题
#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;
}
只是在main中使用std::ref,同时在生产者和消费者中传递Buffer
对象作为引用。如果不使用std::ref
,则此代码将无法编译。
相关文章:
- 为不同配置设置MSVC_RUNTIME_LIBRARY的正确方法是什么
- C++避免重复声明的语法是什么
- 在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么
- 实现无开销push_back的最佳方法是什么
- C++从另一个类访问公共静态向量的正确方法是什么
- "throw expression code" 1e7 >返回 d 是什么?投掷标准::overflow_error( "too big" ) : d;意味 着?
- C++中名称篡改的目的是什么
- 在 c++ 中拥有一组结构的正确方法是什么?
- 这个指针和内存代码打印是什么?我不知道是打印垃圾还是如何打印我需要的值
- 是什么阻止DOMTimerCoordinator::NextID进入无休止的循环
- 派生类销毁的最佳实践是什么
- 这个语法std::class<>{}(arg1, arg2) 在C++中是什么意思?
- 通过JNI传递数据数组的最快方法是什么
- "using namespace std;"在C++的作用是什么?
- 在两台机器之间进行时间戳的最佳c++chrono函数是什么
- 文件系统:复制功能的速度秘诀是什么
- 用常见虚拟函数实现的任意组合来实现派生类的正确方法是什么
- 使用QQuickFramebufferObject时同步数据的最佳方式是什么
- 是什么原因导致它无法编译?它是声明签名还是在函数本身的实现中
- 对于"std::ref"来说,"Hello, World!"的例子是什么?