2010-06-21 11 views
13

मैं बूस्ट पुस्तकालयों पर एक नज़र डाल रहा हूं जो सी ++ की तकनीकी रिपोर्ट 1 में शामिल थे और यह समझने की कोशिश कर रहा था कि प्रत्येक क्या करता है।अगर हमारे पास boost :: bind है तो boost :: mem_fn का उपयोग करने का क्या मतलब है?

मैंने अभी boost::mem_fn के लिए एक उदाहरण चलाया है और अब मैं सोच रहा हूं कि बेहतर boost::bind के बजाय इसका उपयोग करने का क्या मतलब है। जहां तक ​​मैं समझता हूं, उनमें से दोनों सदस्य कार्य को इंगित करने वाली फ़ंक्शन ऑब्जेक्ट लौटाते हैं। मुझे mem_fn इतना सीमित है कि मुझे ऐसा परिदृश्य नहीं मिल रहा है जहां इसका उपयोग bind से बेहतर होगा।

क्या मुझे कुछ याद आ रही है? क्या कोई ऐसा मामला है जिसमें बांध mem_fn को प्रतिस्थापित नहीं कर सकता है?

उत्तर

7

mem_fnbind तुलना में काफी छोटा है, इसलिए यदि आप केवल mem_fn की कार्यक्षमता की जरूरत है उस में खींचने के लिए बहुत कम कोड है।

2

अच्छा, बांध mem_fun पर निर्भर करता है ताकि आप वहां जाएं। हालांकि रोचक होने के बाद से मैं आपके लिए कैसे और क्यों खोजूंगा, मुझे अभी जांच करने का समय नहीं मिला है (बाइंड जटिल है)।

1

boost::lambda आपके द्वारा उल्लेखित दो के साथ कार्यक्षमता का एक समान ओवरलैप है। मुझे लगता है कि वे सभी तरह के इरादे से विकसित होते हैं, लगभग एक ही समय में, विभिन्न दृष्टिकोणों के साथ, जिसके परिणामस्वरूप भ्रम और असंगतता के मुद्दे होते हैं। यह अच्छा होगा अगर वे सभी एक lambda छतरी के नीचे विलय हो जाएंगे।

तो, नहीं, कोई अतिव्यापी डिज़ाइन नहीं है जो दोनों पुस्तकालयों के सह-अस्तित्व के लिए कहता है।

+3

उत्सुक बात यह है कि दोनों 'बाइंड' और 'mem_fn' ने इसे सी ++ तकनीकी रिपोर्ट 1 में बनाया है, और सी ++ समिति काफी सख्त माना जाता है। क्या उन्हें एहसास नहीं हुआ कि वे कार्यशीलताओं को डुप्लिकेट कर रहे हैं? बेंचमार्क कोड के लिए –

5

mem_fn छोटे और bind से तेज है। अपने पसंदीदा संकलक के साथ निम्न कार्यक्रम की कोशिश करो और तुलना करें:

  1. जिसके परिणामस्वरूप निष्पादन के आकार और
  2. खर्च किया जा रहा के रूप में रिपोर्ट सेकंड की संख्या।

आप #if पंक्ति में एक 0 से 1 बदलकर बनाम mem_fnbind के प्रदर्शन की तुलना कर सकते हैं।

#include <iostream> 
#include <functional> 
#include <chrono> 

struct Foo 
{ 
    void bar() {} 
}; 

int main(int argc, const char * argv[]) 
{ 
#if 1 
    auto bound = std::bind(&Foo::bar, std::placeholders::_1); 
#else 
    auto bound = std::mem_fn(&Foo::bar); 
#endif 
    Foo foo; 
    auto start = std::chrono::high_resolution_clock::now(); 
    for(size_t i = 0; i < 100000000; ++i) 
    { 
     bound(foo); 
    } 
    auto end = std::chrono::high_resolution_clock::now(); 
    auto delta = std::chrono::duration_cast< std::chrono::duration<double>>(end - start); 
    std::cout << "seconds = " << delta.count() << std::endl; 
    return 0; 
} 

परिणाम भिन्न होगी, लेकिन मेरे वर्तमान सिस्टम पर निष्पादन के mem_fn संस्करण 220 बाइट्स छोटी है और जितनी जल्दी बारे में दो बार bind संस्करण के रूप में चलाता है।

और एक बोनस सुविधा के रूप में, mem_fn की आवश्यकता नहीं है आप (एक अस्पष्ट टेम्प्लेट की गई संकलक त्रुटि के दर्द पर) bind does तरह std::placeholders::_1 जोड़ने के लिए याद करने के लिए।

तो, जब आप कर सकते हैं mem_fn पसंद करते हैं।

+0

+1। – felipou

+0

मुझे लगता है कि जीसीसी अनुकूलन दोनों के लिए गति दक्षता बनाएगा। मैंने अभी आपके कोड के साथ "-ओ 2" का उपयोग करके परीक्षण किया है (और "बार" फ़ंक्शन में कुछ प्रिंट कर रहा है, अन्यथा ऑप्टिमाइज़र देखेगा कि यह कुछ भी नहीं कर रहा है)। कभी-कभी "बाध्य" संस्करण भी तेज़ होता है। – felipou

+0

आपको कुछ स्थिर 'स्थिर अस्थिर int i; i; '' bar' body में, अन्यथा संकलक खाली फ़ंक्शन कॉल को अनुकूलित कर सकता है (वास्तव में मेरे मामले में 'बाइंड' और' mem_fn' दोनों के साथ क्या होता है)। 'बाइंड' और 'mem_fn' के लिए बेंचमार्क परिणाम मेरे पीसी (* जीसीसी 4.9 *,' -ओ 3') के बराबर है, 'mem_fn' 'बाइंड' से तेज नहीं है। –

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