2013-03-20 57 views
59

有人可以舉一個簡單的例子來演示std::ref的功能嗎?我的意思是一個例子,其中一些其他的構造(如元組或數據類型模板)僅用於,如果不可能在沒有它們的情況下解釋std::ref什麼是「你好,世界!」例如「std :: ref」?

我發現了兩個關於std::refherehere的問題。但是第一個涉及編譯器中的錯誤,第二個使用std::ref的示例不包含std::ref,它們涉及元組和數據類型模板,這些模板使這些示例的理解變得複雜。

+4

http://en.cppreference.com/w/cpp/utility/functional/ref – inf 2013-03-20 17:33:38

回答

79

你應該考慮使用std::ref時功能:

  • 按值
  • 或副本需要模板參數/移動的轉發引用參數,如std::bindstd::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 
+3

這可能值得指出'std :: ref'是可重新綁定的,與傳統的引用不同,如果您將一個引用到模板函數中,這可能很重要。有關示例,請參閱http://stackoverflow.com/questions/37101301/is-this-stdref-behaviour-logical。 – 2016-05-09 03:43:13

15
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時(但其它應用也是可能的當然)封裝的引用。

6

您可能需要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 Concurrency Tutorial - Part 3: Advanced locking and condition variables (Baptiste Wicht) )(我希望我做了正確的歸因)中被盜取的。

+0

在這裏使用'std :: ref'的原因是'thread'的構造函數需要一個參數類型'std :: reference_wrapper' – Deqing 2015-05-06 03:45:46