2013-03-24 9 views
32

हर बार मुझे std::bind का उपयोग करने की आवश्यकता है, मैं इसके बजाय एक लैम्ब्डा का उपयोग कर समाप्त करता हूं। तो मुझे std::bind का उपयोग कब करना चाहिए? मैंने इसे एक कोडबेस से हटा दिया, और मैंने पाया कि लैम्ब्डा std::bind से हमेशा सरल और स्पष्ट थे। std::bind पूरी तरह से अनावश्यक नहीं है? क्या इसे भविष्य में बहिष्कृत नहीं किया जाना चाहिए? मुझे लैम्ब्डा कार्यों में std::bind कब पसंद करना चाहिए? (यह एक कारण होना चाहिए कि यह एक ही समय में लैम्बडास के रूप में मानक हो गया।)मुझे std :: bind का उपयोग कब करना चाहिए?

मैंने यह भी देखा है कि अधिक से अधिक लोग भेड़ के बच्चे से परिचित हैं (इसलिए वे जानते हैं कि लैम्बडा क्या करते हैं)। हालांकि, बहुत कम लोग std::bind और std::placeholders से परिचित हैं।

+0

के संभावित डुप्लिकेट [बाइंड बनाम लैम्ब्डा?] (Http://stackoverflow.com/questions/1930903/bind-vs-lambda) –

+0

देखें stackoverflow.com/a/17545183/1274850 – BertR

उत्तर

28

यहाँ कुछ आप एक लैम्ब्डा के साथ ऐसा नहीं कर सकते है:

std::unique_ptr<SomeType> ptr = ...; 
return std::bind(&SomeType::Function, std::move(ptr), _1, _2); 

lambdas पर कब्जा नहीं कर सकते हैं चाल-केवल प्रकार; वे प्रतिलिपि या lvalue संदर्भ द्वारा मूल्यों को केवल कैप्चर कर सकते हैं। हालांकि स्वीकार्य रूप से यह एक अस्थायी मुद्दा है जिसे सी ++ 14 के लिए सक्रिय रूप से हल किया जा रहा है;)

"सरल और स्पष्ट" राय का विषय है। सरल बाध्यकारी मामलों के लिए, bind बहुत कम टाइपिंग ले सकते हैं। bind पूरी तरह से फ़ंक्शन बाइंडिंग पर केंद्रित है, इसलिए यदि आप std::bind देखते हैं, तो आप जानते हैं कि आप क्या देख रहे हैं। जबकि यदि आप लैम्ब्डा का उपयोग करते हैं, तो आपको यह सुनिश्चित करने के लिए लैम्ब्डा कार्यान्वयन को देखना होगा।

आखिरकार, सी ++ चीजों को कम नहीं करता है क्योंकि कुछ अन्य विशेषता यह कर सकती है जो यह करता है। auto_ptr को हटा दिया गया था क्योंकि यह उपयोग करने के लिए स्वाभाविक रूप से खतरनाक है, और एक गैर-खतरनाक विकल्प है।

+4

+1 देखें। [स्कॉट मेयर्स की आगामी पुस्तक "प्रभावी सी ++ 11"] (http://scottmeyers.blogspot.cz/2013/01/effective-c11-content-and-status.html) में एक आइटम प्रतीत होता है: "* Lambdas को 'std :: bind' * "पर पसंद करें। मेरे पास उस पर टिप्पणी करने के लिए पर्याप्त अंतर्दृष्टि नहीं है, लेकिन यदि आप कर सकते हैं, तो यह बहुत अच्छा होगा। –

+0

इस तरह के एक महान जवाब के लिए धन्यवाद! कदम से कैप्चर करने पर एक लेख है: http://marcoarena.wordpress.com/2012/11/01/learn-how-to-capture-by-move/ उम्मीद है कि हम अगले मानक में स्थानांतरित करके वास्तविक कैप्चर करेंगे । – gnzlbg

+4

सी ++ - 14 लैम्बडा की इस कमी को ठीक करेगा। –

23

आप std::bind साथ बहुरूपी वस्तुओं बना सकते हैं जो आप कर सकते हैं नहीं lambdas के साथ, यानी std::bind द्वारा वापस कॉल आवरण अलग तर्क प्रकार के साथ लागू किया जा सकता है:

#include <functional> 
#include <string> 
#include <iostream> 

struct Polly 
{ 
    template<typename T, typename U> 
    auto operator()(T t, U u) const -> decltype(t + u) 
    { return t + u; } 
}; 

int main() 
{ 
    auto polly = std::bind(Polly(), std::placeholders::_1, "confusing"); 

    std::cout << polly(4) << polly(std::string(" this is ")) << std::endl;  
} 

मैं एक puzzle नहीं एक उदाहरण के रूप में इस बनाया अच्छे कोड का, लेकिन यह पॉलिमॉर्फिक कॉल रैपर प्रदर्शित करता है।

+2

सी ++ 14 जेनेरिक लैम्ब्डा ने इस मुद्दे को हल किया है? – benlong

+11

हां, सी ++ 14 में यह बाइंड अभिव्यक्ति के बराबर है: '[पी = पोली {}] (ऑटो टी) {वापसी पी (टी, "भ्रमित"); } ' –

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