2011-05-25 22 views
7

लेता है फ़ंक्शन पॉइंटर को फ़ंक्शन पॉइंटर घोषित करता है जो एक फ़ंक्शन पॉइंटर को तर्क के रूप में लेते हुए फ़ंक्शन को इंगित करता है?फंक्शन पॉइंटर जो एक फ़ंक्शन पॉइंटर

typedef void (*fnptr)(void (*)()); 

void func(fnptr) 
{ 
    /* ... */ 
} 

void func2(fnptr) 
{ 
    /* ... */ 
} 

void main() 
{ 
    fnptr fn = &func; 
    func2(fn); 
} 

यह संभव है:

मैं सफलता के बिना निम्नलिखित की कोशिश की है?

+1

इम यकीन नहीं करता है, तो आप कर सकते हैं, यह अपने आप के साथ कुछ templatize करने की कोशिश कर की तरह हो सकता है, तो आप सिर्फ एक पुनरावर्ती घोषणा –

+0

अंत मैं नहीं बल्कि लगता है कि यह नहीं किया जा सकता। –

+2

सिर्फ एक सामान्य घोषणा और एक स्पष्ट कलाकार का उपयोग करने के बारे में कैसे? – casablanca

उत्तर

13

मुझे बहुत संदेह है, लेकिन आप एक स्ट्रक्चर पेश करके आवश्यक रिकर्सन प्राप्त कर सकते हैं। उपयोग की

struct Rec; 

typedef void (*RecFun)(const Rec&); 

struct Rec { 
    RecFun fun; 
}; 

उदाहरण:

#include <iostream> 

void nothing(const Rec& rec) {} 
Rec recNothing = { nothing }; 

void f(const Rec& rec) 
{ 
    std::cout << "f\n"; 
    rec.fun(recNothing); 
} 
Rec recF = { f }; 

void g(const Rec& rec) 
{ 
    std::cout << "g\n"; 
    rec.fun(recNothing); 
} 
Rec recG = { g }; 

int main() 
{ 
    recF.fun(recG); 
} 

अद्यतन: के रूप में क्रिस, वाइटस, और जोहान्स के सुझावों के अनुसार, यहाँ कुछ सुविधाजनक अंतर्निहित रूपांतरण हैं (जैसा कि हर्ब में सुतर की GotW #57):

struct Rec; 

typedef void (*RecFun)(const Rec&); 

struct Rec { 
    RecFun fun; 
    Rec(RecFun fun) : fun(fun) {} 
    operator RecFun() const { return fun; } 
}; 
+1

+1 रिकर्सन समस्या के प्रबंधन के लिए सुरुचिपूर्ण विधि। – dusktreader

+1

यदि आप उस वाक्यविन्यास –

+0

परफेक्ट उत्तर पसंद करते हैं तो आप 'ऑपरेटर()' को ओवरराइड भी कर सकते हैं ताकि यह एक फ़ंक्शन (एक मज़ेदार) जैसा दिखता और व्यवहार करता हो। आपका बहुत बहुत धन्यवाद! : डी –

0

बस टाइप करने के लिए सबसे आसान तरीका है। एक समारोह सूचक बस किसी भी अन्य प्रकार की तरह एक पैरामीटर है:

typedef (* InnerFunctionPtr)(void); 
typedef (* OuterFunctionPtr)(InnerFunctionPtr); 

संपादित करें: लोगों ने बताया है कि आप दोनों एक ही प्रकार के होने का मतलब है। उस स्थिति में, यह संभव नहीं है, क्योंकि प्रकार रिकर्सिव होगा। एक पूर्ण प्रकार विनिर्देश बनाना असंभव है (फ़ंक्शन के पैरामीटर का प्रकार कभी भी पूरी तरह से निर्दिष्ट नहीं किया गया है, ergo ...)

+2

मुझे लगता है कि ओपी का मतलब एक ही प्रकार का तर्क है। – casablanca

+0

'OuterFunctionPtr' को तर्क के रूप में 'OuterFunctionPtr' लेना होगा। –

+0

-1। गलत टाइपपीफ! – Nawaz

0

हां, यह नहीं किया जा सकता है। यह अच्छा होगा अगर आप typename का उपयोग टाइपिफ़ को घोषित करने के लिए कर सकते हैं; कुछ की तरह:

typename fnptr; 
typedef (*fnptr)(fnptr); 

लेकिन वह काम नहीं करता, क्योंकि typename में कुछ विशिष्ट टेम्पलेट के लिए प्रतिबंधित है का उपयोग करता है

0

यह इस तरह से संभव है:

typedef void (*fnptr)(void (*)()); 

fnptr fn1,fn2; 
void func(fn1) 
{ 
/* ... */ 
} 

void func2(fn2) 
{ 
/* ... */ 
} 
void main() 
{ 
fnptr fn = &func; 
func2(fn); 
} 
0

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

स्पष्ट रूप से अनुशंसित नहीं है, लेकिन इसे वहां से बाहर रखा गया है।

typedef void (*fnptr)(void (*)()); 

void func(void (*x)()) 
{ 
    fnptr f = (fnptr)x; 
    /* ... */ 
} 

void func2(void (*x)()) 
{ 
    fnptr f = (fnptr)x; 
    /* ... */ 
} 

void main() 
{ 
    fnptr fn = &func; 
    func2((void (*)())fn); 
} 
संबंधित मुद्दे