2013-07-02 10 views
19

मैं निम्नलिखित कोड है:std :: बाँध संदर्भ खो देते हैं जब rvalue संदर्भ के रूप में वितरित

#include <stdio.h> 
#include <functional> 

template <typename T> 
auto callback(T&& func) ->decltype(func()) 
{ 
    return func(); 
} 

double test(double& value) 
{ 
    value=value+1.0; 
    return value; 
} 

int main(void) 
{ 
    double t=1.0; 
    printf("%f\n",t); 
    test(t); 
    printf("%f\n",t); 
    callback(std::bind(test,t)); 
    printf("%f\n",t); 
} 

और यह

1.000000 
2.000000 
2.000000 

callback समारोह का तात्पर्य कौन सा बजाय t की एक प्रति मिली एक के आउटपुट t का संदर्भ। मैं सोच रहा हूं कि क्या हुआ, क्योंकि std::bind के लिए यह सही-अग्रेषण होना चाहिए।

उत्तर

33

std::bind डिफ़ॉल्ट रूप से मूल्य semantics का उपयोग करता है। यह एक सेन डिफ़ॉल्ट है जो आपको निम्न प्रकार की चीज़ों को सुरक्षित रूप से करने देता है।

int f(double x); 

auto fun = std::bind(f, 1.0); // stores a copy, not a reference to a temporary 
fun(); 

मूल्य semantics का उपयोग सुरक्षित है: बाध्य तर्क का जीवनकाल बाइंड द्वारा लौटाई गई वस्तु का जीवनकाल बन जाता है। संदर्भ अर्थशास्त्र का उपयोग करने की गारंटी नहीं होगी। इसलिए जब आप संदर्भ अर्थशास्त्र चाहते हैं तो आपको स्पष्ट होना आवश्यक है; अगर आपको परेशानी हो रही है तो यह तुम्हारी गलती है। आदेश में है कि आप std::ref उपयोग करने की आवश्यकता करने के लिए:

int main(void) 
{ 
    double t=1.0; 
    printf("%f\n",t); 
    test(t); 
    printf("%f\n",t); 
    callback(std::bind(test, std::ref(t))); 
    printf("%f\n",t); 
} 

यह वही प्रोटोकॉल, मानक पुस्तकालय में कहीं प्रयोग किया जाता है std::thread निर्माता की तरह।

8

std::bind() मूल्य semantics (as R. Martinho Fernandes nicely explains in his answer) के लिए डिज़ाइन किया गया है, और आंतरिक रूप से प्रतियां बनाते हैं। आपको क्या करना होगा/चाहते std::ref है:

callback(std::bind(test, std::ref(t))); 
//      ^^^^^^^^^^^ 

std::ref रिटर्न एक std::reference_wrapper<> उद्देश्य यह है कि अपने मूल तर्क के लिए एक संदर्भ गिर्द घूमती है। इस तरह, reference_wrapper ऑब्जेक्ट t के आसपास ऑब्जेक्ट की प्रतिलिपि बनाई गई है, और t स्वयं नहीं है।

यह आपको वैल्यू सेमेन्टिक्स (डिफ़ॉल्ट रूप से माना जाता है) और संदर्भ अर्थशास्त्र (जिसमें आपके स्पष्ट हस्तक्षेप की आवश्यकता होती है) के बीच चयन करने की अनुमति देता है।

यहां एक live example है।

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