2013-03-20 5 views
59

क्या कोई एक साधारण उदाहरण दे सकता है जो std::ref की कार्यक्षमता को प्रदर्शित करता है? मेरा मतलब है कि एक उदाहरण जिसमें कुछ अन्य संरचनाएं (जैसे टुपल्स, या डेटा टाइप टेम्पलेट्स) का उपयोग केवल के बिना किया जाता है, उनके बिना std::ref समझा जाना असंभव है।"हैलो, वर्ल्ड!" क्या होगा "std :: ref" के लिए उदाहरण?

मुझे std::refhere और here के बारे में दो प्रश्न मिले। लेकिन पहले में यह एक कंपाइलर में एक बग के बारे में जाता है और दूसरे में, std::ref के उपयोग के उदाहरणों में std::ref नहीं होते हैं और उनमें ट्यूपल्स और डेटा प्रकार टेम्पलेट्स शामिल होते हैं जो इन उदाहरणों को जटिल बनाते हैं।

+4

http://en.cppreference.com/w/cpp/utility/functional/ref – inf

उत्तर

79

आप 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 
+3

शायद यह इंगित करने लायक है कि 'std :: रेफरी एक पारंपरिक संदर्भ के विपरीत, पुनर्विचार योग्य है, इससे कोई फर्क नहीं पड़ता कि आप टेम्पलेट फ़ंक्शन में किसी को खिला रहे हैं। उदाहरण के लिए http://stackoverflow.com/questions/37101301/is-this-stdref-behaviour-logical देखें। –

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' का उपयोग करने का कारण,' थ्रेड 'के निर्माता को' std :: context_wrapper' के पैरामीटर प्रकार की आवश्यकता होती है – Deqing

संबंधित मुद्दे