What would be a “Hello, World!” example for “std::ref”?

后端 未结 4 2044
星月不相逢
星月不相逢 2021-01-30 01:54

Can somebody give a simple example which demonstrates the functionality of std::ref? I mean an example in which some other constructs (like tuples, or data type tem

相关标签:
4条回答
  • 2021-01-30 02:44

    You should think of using std::ref when a function:

    • takes a template parameter by value
    • or copies/moves a forwarding reference parameter, such as std::bind or the constructor for std::thread.

    std::ref is a value type that behaves like a reference.

    This example makes demonstrable use of 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;
    }
    

    Output:

    0
    1
    
    0 讨论(0)
  • 2021-01-30 02:48
    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 is mainly used to encapsulate references when using std::bind (but other uses are possible of course).

    0 讨论(0)
  • 2021-01-30 02:50

    Another place where you may need std::ref is when passing objects to threads where you want each thread to operate on the single object and not a copy of the object.

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

    where you wish various functions running in various threads to share a single buffer object. This example was stolen from this excellent tutorial ( C++11 Concurrency Tutorial - Part 3: Advanced locking and condition variables (Baptiste Wicht) ) (hope I did the attribution correctly)

    0 讨论(0)
  • 2021-01-30 02:56

    // Producer Consumer Problem

    #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;
    }
    

    Just another use of std::ref in main while passing Buffer object as reference in producer and consumer. If std::ref not used then this code will not compile.

    0 讨论(0)
提交回复
热议问题