2011-08-18 19 views
8

क्षमा करें अगर इससे पहले पूछा गया है, लेकिन मैं इसे खोजने में असमर्थ था।फ़ंक्शन पॉइंटर के बजाय मान (?) द्वारा फ़ंक्शन पास करें?

तो मैं खुद को टेम्पलेट्स और नई सी ++ 11 विशेषताओं (मुख्य रूप से लैम्बडास, जो मुझे हमेशा अन्य भाषाओं में पसंद आया) के बारे में शिक्षित करने की कोशिश कर रहा हूं।

लेकिन मेरे परीक्षण में मैं कुछ मुझे नहीं पता कि यह काम किया था के लिए आया था, और मैं समझने के लिए कि यह कैसे लेकिन नहीं कर सकते यह आंकड़ा बाहर ..

निम्नलिखित कोड काम करता है कोशिश कर रहा हूँ:

template <class Func> 
void Test(Func callback) { 
    callback(3); 
} 

void Callback(int i) { 
    std::cout << i << std::endl; 
} 

int main(int argc, char** argv) { 
    Test(&Callback); // this I was expecting to work, compiler will see its a pointer to a function 
    Test(Callback); // this also works, but how?! 
    return 0; 
} 

यदि मैं समझता हूं कि टेम्पलेट कैसे काम करते हैं, मूल रूप से वे कंपाइलर के लिए एक योजना है जो जानने के लिए है, तो पहला कॉल Test(&Callback); मैं काम करने की उम्मीद कर रहा था क्योंकि संकलक को टेम्पलेट को एक फ़ंक्शन पता प्राप्त होगा और तर्कों को मानना ​​चाहिए एक सूचक बनो।

लेकिन दूसरी कॉल क्या है? यह मानते हुए टेम्पलेट क्या है? एक Functio की एक प्रति (अगर यह भी कोई समझ में आता है)?

उत्तर

14

एक फ़ंक्शन पूरी तरह से एक सूचक के लिए परिवर्तनीय है; यह रूपांतरण हर जगह बहुत ज्यादा होता है। Test(Callback) बिल्कुल Test(&Callback) जैसा ही है। इसमें कोई फर्क नही है। दोनों मामलों में, Funcvoid(*)(int) होने के लिए घटाया गया है।

फ़ंक्शन पॉइंटर्स अजीब हैं। आप उनके बारे में अधिक जानकारी प्राप्त कर सकते हैं "Why do all these crazy function pointer definitions all work?"

+0

उत्तर के लिए धन्यवाद। इसलिए यदि मैंने टेम्पलेट्स का उपयोग नहीं किया और परीक्षण घोषित किया: शून्य परीक्षण (शून्य (* कॉलबैक) (int)) {...} दोनों कॉल भी काम करेंगे। यह जानकर अच्छा लगा। बीमार सुनिश्चित करें कि मैंने आपके द्वारा जुड़े धागे को पढ़ा है। – sap

3

सी ++ में, फ़ंक्शंस प्रथम श्रेणी की ऑब्जेक्ट्स नहीं हैं, जिसका अर्थ है "मूल्य के रूप में कार्य करें" इसमें कोई अर्थ नहीं है। यही कारण है कि फ़ंक्शन का नाम हमेशा सूचक के लिए स्पष्ट रूप से परिवर्तनीय रहा है।

+0

हो सकता है कि वहां ऐसी भाषाएं हों, जहां "मूल्य से कार्य" समझ में आता है। – hamstergene

2

कार्य फ़ंक्शन पॉइंटर्स के लिए पूरी तरह से परिवर्तनीय हैं। यदि वास्तव में कोई कार्य मूल्य या संदर्भ प्राप्त करने का कोई तरीका नहीं है। हालांकि विचित्र रूप से आप एक फ़ंक्शन वैल्यू प्रकार बना सकते हैं, आप बस इसे कुछ भी असाइन नहीं कर सकते हैं।

Here is code snippit जो दर्शाता है कि कैसे लैम्ब्डा और विभिन्न कॉलबैक टेम्पलेट्स के साथ प्रतिक्रिया करते हैं।

+0

कोड के लिए धन्यवाद, वास्तव में मददगार। – sap

+0

यह गलत है। फंक्शन संदर्भ ठीक हैं। यदि 'टेस्ट' को 'शून्य परीक्षा (फनक और कॉलबैक)' के रूप में घोषित किया गया था, तो 'फनक' को 'शून्य (int)' तक घटाया जाएगा, और 'कॉलबैक' संदर्भ द्वारा पारित किया जाएगा, बिना किसी सूचक में परिवर्तित किए, ' Test'। –

+0

वाह! मुझे लगता है कि यह समझ में आता है कि संदर्भ को समर्थन के साथ-साथ पॉइंटर्स भी समर्थित होना चाहिए क्योंकि वे बहुत समान हैं। क्या फ़ंक्शन वैल्यू घोषित करना संभव है, और इसे कुछ असाइन करना संभव है? –

0

सी ++ 11 (और बूस्ट और टीआर 1) में हमारे पास std :: फ़ंक्शन टेम्पलेट्स, लैम्बडा और फ़ंक्शंस को संग्रहीत करने के लिए टेम्पलेट प्रकार के रूप में है। तो आप निश्चित रूप से प्रकार std :: फ़ंक्शन के चर के फ़ंक्शन मान को रखने की अवधारणा रख सकते हैं। वह चर "खाली" भी हो सकता है जिसका अर्थ है कि इसमें कोई फ़ंक्शन (संदर्भ) संग्रहीत नहीं होता है। फिर इसे नहीं कहा जा सकता है।

मूल प्रश्न सी से विपरीत है, सी ++ फ़ंक्शन संदर्भों की अनुमति देता है। इसके अलावा, सी के साथ संगतता कारणों के लिए एक फ़ंक्शन नाम फ़ंक्शन पॉइंटर में खराब हो सकता है। लेकिन सी ओवरिंग चीजों की वजह से सी ++ में सी ++ में सी 0+ से अधिक "दिलचस्प" सी

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