2015-02-06 12 views
5

को गतिशील functor पासिंग मैं अपेक्षाकृत ग नया हूँ ++ और यह मेरा बहुत पहली पोस्ट है, तो कोमल हो ;-)एसटीएल

मैं समझता हूँ कि कैसे समारोह संकेत या समारोह वस्तुओं पारित करने के लिए, जैसे कई STL कार्यों की आवश्यकता है। यह मेरे लिए अस्पष्ट है कि विरासत के साथ संयोजन में इसका उपयोग कैसे करें।

विशेष रूप से मैं कई functors कि एक आधार functor से विरासत के साथ एक STL समारोह कॉल करना चाहते हैं। मुझे इस विषय पर कोई प्रासंगिक टिप्पणी या सर्वोत्तम प्रथा नहीं मिली है। यहाँ एक सरल कोड का टुकड़ा:

struct generator{ 
    virtual int operator()() = 0; 
    virtual ~generator(){}; 
}; 

struct A : public generator{ 
    int operator()(); 
}; 

struct B : public generator{ 
    int operator()(); 
}; 

int main() 
{ 
    auto v = std::vector<std::array<int, 500>>(2); 
    std::array<std::shared_ptr<generator>, 2> functors = {{std::make_shared<A>(), 
                 std::make_shared<B>()}}; 
    for (size_t i = 0; i < functors.size(); ++i) 
    std::generate(std::begin(v[i]), std::end(v[i]), 
        *(functors[i])); 
    return 0; 
} 

संकलन इस देता है:

clang++ -std=c++11 -g -Wall -Wextra test_stackoverflow.cpp 
test_stackoverflow.cpp:25:5: error: no matching function for call to 'generate' 
    std::generate(std::begin(v[i]), std::end(v[i]),*(functors[i])); 
    ^~~~~~~~~~~~~ 
/usr/lib/gcc/i686-linux-gnu/4.6/../../../../include/c++/4.6/bits/stl_algo.h:5003:5: note: candidate template ignored: substitution 
     failure [with _ForwardIterator = int *, _Generator = generator]: parameter type 'generator' is an abstract class 
    generate(_ForwardIterator __first, _ForwardIterator __last, 

हाँ * के प्रकार (functors [i]) जनरेटर है। जो ए :: ऑपरेटर() और बी :: ऑपरेटर() तक गतिशील पहुंच की अनुमति नहीं देगा। मैं समझता हूं कि कैसे (मूल रूप से) इसे हल करें। जैसे

std::generate(std::begin(v[i]), std::end(v[i], 
       [&]{ return functors[i]->operator()(); }; 

हालांकि इस बल्कि सुलझा लगता है और मैं एक स्पष्ट तरीका अपने लक्ष्यों को प्राप्त करने के लिए देख रहा हूँ।

कोई आमतौर पर ऐसे गतिशील फ़ैक्टर को कैसे पास करता है। या अगर यह फहरा हुआ है, तो सबसे अच्छा विकल्प क्या है?

किसी भी मदद या सुझाव का स्वागत है।

उत्तर

1

समस्या, जैसा कि आप पहले से ही पता हो सकता है, कि std::generate मूल्य द्वारा जनरेटर लेता है। एक बहुलक वस्तु को पारित करने के लिए, आपको संदर्भ से गुजरना होगा।

और सी ++ 11 में इस तरह की समस्या के लिए एक समाधान है (लैम्ब्डा विकल्प के अलावा, जो कि सी ++ 11 से पहले हमारे पास था उससे कहीं अधिक सुरुचिपूर्ण है, मुझे विश्वास है)। समाधान std::ref है। यह एक संदर्भ रैपर देता है जिसे मूल्य से पारित किया जा सकता है। , तुम क्यों एक functor के रूप में संदर्भ रैपर पारित कर सकते हैं

std::generate(std::begin(v[i]), std::end(v[i]), 
       std::ref(*(functors[i]))); 

कारण यह है कि वे operator()

+0

भी लागू है 'std :: function' –

+0

की पुष्टि की, कर सकते हैं:

यह आप के लिए काम करना चाहिए एल्गोरिदम के लिए 'std :: ref' पास करें। वह नहीं जानता था। http://coliru.stacked-crooked.com/a/db815184c44240ad –

+0

मैं ईमानदार रहूंगा। मैंने कभी std :: ref के बारे में नहीं सुना होगा। तो इसके लिए आपका शुक्रिया। क्या आप राय मानते हैं कि इस पर एक लैम्ब्डा पसंद किया जाना चाहिए, और यदि ऐसा है तो क्यों? – APevar