मैं वाक्य रचना का उपयोग करके C ++ 11 के साथ एक फ़ंक्शन पॉइंटर को कैसे टाइप कर सकता हूं?


171

मैं यह लिखना चाहूंगा

typedef void (*FunctionPtr)();

का उपयोग कर using। मुझे यह कैसे करना है?


2
usingवास्तव में बहुत आत्मविश्वास , विशेष रूप से क्योंकि फ़ंक्शन पॉइंटर आइडेंटिफ़ायर आमतौर पर एक typedefबयान के बीच में रहते हैं और सामने की ओर बढ़ते हैं using। कम से कम मैं वहीं खो गया हूं।
21

जवाबों:


180

आपके पास एक समान सिंटैक्स है, सिवाय इसके कि आप सूचक से पहचानकर्ता को हटा दें:

using FunctionPtr = void (*)();

यहाँ एक उदाहरण है

यदि आप "बदसूरती दूर करना" चाहते हैं, तो कोशिश करें कि Xeo ने क्या सुझाव दिया:

#include <type_traits>

using FunctionPtr = std::add_pointer<void()>::type;

और यहाँ एक और डेमो है


25
डांग, मुझे आशा है कि यह बदसूरती को दूर कर देगा:(
13'15

10
@rubenvb: using FunctionPtr = AddPointer<void()>;;)
Xeo

2
टेम्प्लेट प्रकार के उपनामों को और अधिक साफ करने के लिए उपयोग करना संभव है add_pointer<void()>::type: यहां सुझाव का उपयोग करते हुए: group.google.com/a/isocpp.org/d/msg/std-proposals/xDQR3y5uTZ0/… आप लिख सकते हैं pointer<function<void>>
bames53

5
इन प्रकार के उपनाम अस्पष्ट, टाइप-आउट सिंटैक्स से साधारण बाएं से दाएं सिंटैक्स में टाइप सिंटैक्स को बदलते हैं, जो विशिष्ट एपीआई के लिए कस्टम टाइपफीड की आवश्यकता को समाप्त करता है जो कि एपीआई के यौगिक प्रकारों को लिखना आसान बनाता है।
bames53

10
C ++ 14 में, आप लिखने में सक्षम होंगे: FunctionPtr = std :: add_pointer_t <void ()> का उपयोग करके;
आंद्रेजेज

46

"कुरूपता" को भी दूर किया जा सकता है यदि आप एक सूचक टाइप करने वाले से बचते हैं:

void f() {}
using Function_t = void();    
Function_t* ptr = f;
ptr();

http://ideone.com/e1XuYc


यह एक दिलचस्प दृष्टिकोण है, हालांकि मैं चिंतित हो सकता हूं कि मैं *बाद में भूल जाऊंगा और भ्रमित करने वाली त्रुटियां प्राप्त करूंगा ।
अपोलिस ने मोनिका जूल

यह निश्चित रूप से यहाँ प्रस्तुत सबसे अच्छा संस्करण है। धन्यवाद। और मैं एक पॉइंटर देखना पसंद करता हूं, क्योंकि यह एक फ़ंक्शन पॉइंटर है।
पियरे

13

आप एक चाहते हैं type-id, जो अनिवार्य रूप से एक घोषणा के समान है, सिवाय इसके कि आप हटाएं declarator-iddeclarator-idआम तौर पर एक पहचानकर्ता है, और नाम आप बराबर घोषणा में घोषित कर रहे हैं।

उदाहरण के लिए:

int x

declarator-idहै xतो बस इसे हटाने:

int

इसी तरह:

int x[10]

निकालें x:

int[10]

अपने उदाहरण के लिए:

void (*FunctionPtr)()

यहाँ declarator-idहै FunctionPtr। तो बस इसे पाने के लिए इसे हटा दें type-id:

void (*)()

यह काम करता है क्योंकि दिए गए type-idआप हमेशा विशिष्ट रूप से निर्धारित कर सकते हैं जहां पहचानकर्ता एक घोषणा बनाने के लिए जाएगा। मानक में 8.1.1 से:

[टाइप-आईडी] में विशिष्ट स्थान की पहचान करना संभव है जहां निर्माण [घोषणा] होने पर पहचानकर्ता प्रकट होगा। नामित प्रकार तब काल्पनिक पहचानकर्ता के प्रकार के समान है।


9

कैसे स्पष्टता के लिए इस वाक्यविन्यास के बारे में? (नोट डबल कोष्ठक)

void func();
using FunctionPtr = decltype((func));

1
इस संदर्भ में डबल कोष्ठक का क्या अर्थ है? एक संदर्भ एक समारोह सूचक के लिए?
0x499602D2

5
आपका FunctionPtrकोई फ़ंक्शन पॉइंटर नहीं है, लेकिन decltype(&f), यहां देखें ।
रुबेंवब

@ 1234597890 फंक्शनप्रोट 'वॉयड ()'
लियो गुडस्टैंड

@rubenvb: आप सही कह रहे हैं। यह एक फ़ंक्शन पॉइंटर नहीं है, लेकिन फ़ंक्शन (प्रकार) के लिए एक अंतराल संदर्भ है। यही कारण है कि static_assert विफल रहता है ... <br/> फ़ंक्शनपार्ट का उपयोग करने का प्रयास करें: नेमस्पेस std का उपयोग करके; #include <iostream> void do_f () {cerr << "क्या? \ n"; } शून्य च (); FunctionPtr = घोषणापत्र ((एफ)) का उपयोग करना; FunctionPtr2 = घोषणापत्र (& f) का उपयोग करना; // काम नहीं करता है // FunctionPtr3 का उपयोग करके = घोषणापत्र (एफ); int main () {FunctionPtr ff = do_f; एफएफ (); FunctionPtr2 ff2 = do_f; FF2 (); }
लियो गुडस्टैंड

1

एक अन्य दृष्टिकोण ऑटो रिटर्न प्रकार का उपयोग कर रिटर्न रिटर्न प्रकार के साथ हो सकता है।

using FunctionPtr = auto (*)(int*) -> void;

यह कुछ बताने में सक्षम होने का तर्कपूर्ण लाभ है एक फ़ंक्शन ptr जब उपनाम "ऑटो (*)" से शुरू होता है और यह पहचानकर्ता नामों से बाधित नहीं होता है।

तुलना

typedef someStructureWithAWeirdName& (FunctionPtr*)(type1*, type2**, type3<type4&>);

साथ में

using FunctionPtr = auto (*)(type1*, type2**, type3<type4&>) -> someStructureWithAWeirdName&;

डिस्क्लेमर: मैंने इसे बीन डीन की "इजीइंग इन मॉडर्न सी ++" टॉक से लिया

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.