libstdC++ के std::function
में हम एक यूनियन प्रकार का उपयोग करते हैं जो उचित रूप से आकार और प्वाइंटर्स, फ़ंक्शन पॉइंटर्स या पॉइंटर्स को सदस्य कार्यों में संग्रहीत करने के लिए गठबंधन किया जाता है। हम किसी भी समारोह उद्देश्य यह है कि कि आकार और संरेखण, लेकिन में संग्रहित किया जा सकता है के लिए एक ढेर आवंटन केवल अगर यह होता है "स्थान अपरिवर्तनीय"
/**
* Trait identifying "location-invariant" types, meaning that the
* address of the object (or any of its members) will not escape.
* Also implies a trivial copy constructor and assignment operator.
*/
कोड std::tr1::function
कार्यान्वयन पर आधारित है और वह हिस्सा hasn 'से बचने टी महत्वपूर्ण रूप से बदल गया। मुझे लगता है कि std::aligned_storage
का उपयोग करके सरलीकृत किया जा सकता है और विशेषता को विशेषज्ञता देकर इसे बेहतर किया जा सकता है ताकि अधिक प्रकार के स्थान invariant के रूप में पहचाना जा सके।
लक्ष्य ऑब्जेक्ट को आमंत्रित करना किसी वर्चुअल फ़ंक्शन कॉल के बिना किया जाता है, टाइप एरर std::function
में एक फ़ंक्शन पॉइंटर को संग्रहीत करके किया जाता है जो फ़ंक्शन टेम्पलेट विशेषज्ञता का पता होता है। सभी ऑपरेशन संग्रहीत सूचक के माध्यम से उस फ़ंक्शन टेम्पलेट को कॉल करके और एक enum में गुजरने के द्वारा किया जाता है यह पहचानने के लिए कहा जा रहा है कि कौन सा ऑपरेशन किया जा रहा है। इसका मतलब कोई vtable नहीं है और ऑब्जेक्ट में केवल एक ही फ़ंक्शन पॉइंटर को संग्रहीत करने की आवश्यकता है।
इस डिजाइन को मूल boost::function
लेखक द्वारा योगदान दिया गया था और मेरा मानना है कि यह बढ़ावा कार्यान्वयन के करीब है। बूस्ट के लिए Performance दस्तावेज़ देखें। कुछ तर्क के लिए समारोह। इसका मतलब है कि यह बहुत संभावना नहीं है कि जीसीसी का std::function
boost::function
से भी तेज है, क्योंकि यह एक ही व्यक्ति द्वारा समान डिजाइन है।
एनबी। हमारे std::function
अभी तक एक आवंटक के साथ निर्माण का समर्थन नहीं करता है, किसी भी आवंटन को करने की आवश्यकता है new
का उपयोग करके किया जाएगा।
एमिल की टिप्पणी के जवाब में एक std::function
जो सदस्य समारोह और एक वस्तु के लिए सूचक धारण के लिए एक ढेर आवंटन से बचने के लिए एक इच्छा व्यक्त, यहाँ यह करने के लिए एक छोटे से हैक है (लेकिन आप से यह नहीं सुना मुझे ;-)
struct A {
int i = 0;
int foo() const { return 0; }
};
struct InvokeA
{
int operator()() const { return a->foo(); }
A* a;
};
namespace std
{
template<> struct __is_location_invariant<InvokeA>
{ static const bool value = true; };
}
int main()
{
A a;
InvokeA inv{ &a };
std::function<int()> f2(inv);
return f2();
}
चाल कि InvokeA
काफी छोटा function
की छोटी सी वस्तु बफर में फिट करने के लिए है, और विशेषता विशेषज्ञता उस में वहाँ स्टोर करने के लिए सुरक्षित है कहते हैं, तो function
कि की एक प्रति को धारण करता है ढेर पर नहीं, सीधे वस्तु।यह a
की आवश्यकता है जब तक यह करने के लिए सूचक बनी रहती है लागू करने के लिए है, लेकिन स्थिति वैसे भी हो सकता है अगर function
के लक्ष्य bind(&A::foo, &a)
था।
'std :: function' एक अंतरफलक, नहीं एक कार्यान्वयन है। आप कुलपति ++ के stdlib, libstdC++, या libC++ _specifically_ के बारे में पूछना चाहते हैं तो यह एक मान्य सवाल है, लेकिन जैसा कि-है आपके सवाल का दायरा बहुत अधिक व्यापक – ildjarn
@ildjarn है: सवाल का अंतिम वाक्य पढ़ें। वह विशिष्ट कार्यान्वयन के बारे में पूछ रहा है, और सबसे विशेष रूप से libstdC++ के बारे में पूछ रहा है। – abarnert
@abarnert: इसे पढ़ने के बिना मैं इसका जवाब कैसे दे सकता हूं? जाहिर है, मैंने इसे पढ़ा, और मुझे यह व्यापक रूप से व्यापक लगता है। – ildjarn