2015-05-06 17 views
8

std::async के लिए सीधे rvalue संदर्भ मानकों के साथ lambdas बंधन, std::async compiles के माध्यम से एक लैम्ब्डा के लिए एक rvalue बंधन और अपेक्षा के अनुरूप निष्पादित करता है के बारे में इस comment से प्रेरित होकर: (live example (live example)अंतर जब लपेटकर rvalue संदर्भ लैम्ब्डा

auto lambda = [] (std::string&& message) { 
    std::cout << message << std::endl; 
}; 
auto bound = std::bind(lambda, std::string{"hello world"}); // Compiler error 
bound(); 

इसका कारण यह है है:)

auto lambda = [] (std::string&& message) { 
    std::cout << message << std::endl; 
}; 
auto future = std::async(lambda, std::string{"hello world"}); 
future.get(); 

std::bind का उपयोग करते हुए, हालांकि, एक संकलक त्रुटि से चलाता है std::bindmessage को एक lvalue के रूप में रखता है, ताकि जब यह लैम्ब्डा को पास कर लेता है, तो तर्क अब पैरामीटर से मेल नहीं खाता है।

मैं read कि std::async आंतरिक std::bind का उपयोग करता है, तो यह कैसे rvalue संदर्भ मानकों के साथ दूर प्राप्त करता है जब std::bind नहीं करता है? क्या मानक का कोई विशेष हिस्सा है जिसके लिए इस व्यवहार की आवश्यकता है या यह संकलक पर निर्भर है?

उत्तर

4

I've read that std::async internally uses std::bind , so how does it get away with rvalue reference parameters when std::bind does not?

यह आंतरिक रूप से bind का उपयोग नहीं करता है। (या इसके बजाय, यह @Praetorian's answer in that question में किसी महाकाव्य के विपरीत नहीं जा सका, और कुछ अलग लिखना बहुत आसान है)।

यह आमतौर पर कुछ हद तक एक bind तरह मशीनरी का उपयोग कर कार्यान्वित किया जाता है, लेकिन यह क्योंकि यह अजीब चीजों के सभी प्रकार bind हैंडल (नेस्ट bind रों, प्लेसहोल्डर, अतिरिक्त तर्क छोड़ने, आदि) को संभालने के लिए नहीं है बहुत सरल है

Is there a particular part of the standard that requires this behavior or is this dependent on the compiler?

यह मानक द्वारा आवश्यक है। bind का विनिर्देश हास्यास्पद रूप से घना है, लेकिन इसके लिए सादे बाध्य तर्कों को अंतराल ([func.bind.bind]/p10, बुलेट 4) के रूप में पारित करने की आवश्यकता होती है।

asyncINVOKE (DECAY_COPY (std::forward<F>(f)), DECAY_COPY (std::forward<Args>(args))...) पर कॉल करने के लिए निर्दिष्ट है, और DECAY_COPY हमेशा एक रैल्यू देता है।

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