2010-07-27 9 views
5
int foo(int){  
    ... 
} 

कोई विचार?सी ++ में, कार्यों की परिभाषा में, तर्क पहचानकर्ता वैकल्पिक हैं। किस परिदृश्य में यह सुविधा उपयोगी हो सकती है?

+1

नोट, यह केवल सी ++ के लिए सच है और सी के लिए नहीं। मैं सी टैग के कारण इसका उल्लेख करता हूं। – quinmars

+0

धन्यवाद, मैंने अंतर को रेखांकित करने के लिए सी टैग का उपयोग किया। –

+0

ऐसा नहीं है कि टैग का उपयोग कैसे किया जाता है। यदि मैं "सी" के साथ टैग किए गए सभी विषयों की खोज करता हूं, तो मुझे उन विषयों को खोजने की उम्मीद नहीं है जो सी से प्रासंगिक नहीं हैं। इसका कोई मतलब नहीं है, इसलिए मैंने टैग हटा दिया। –

उत्तर

7

ही एक मामला है जहाँ आप एक समारोह को परिभाषित लेकिन पैरामीटर नाम नहीं स्कॉट Meyers के "प्रभावी सी ++, 3 संस्करण" में दी गई है, मद 47:

template<typename IterT, typename DistT> 
void advance(IterT& iter, DistT d) 
{ 
    doAdvance(iter, d, 
      typename std::iterator_traits<IterT>::iterator_category()); 
} 
:

template<typename IterT, typename DistT>   
void doAdvance(IterT& iter, DistT d,    
       std::random_access_iterator_tag) 
{ 
    iter += d; 
} 

में प्रयोग किया जाता है

अनिवार्य रूप से, doAdvance में तीसरा पैरामीटर एक चर नाम से unaccompanied है, यानी यह एक अनाम पैरामीटर है। एक अनाम पैरामीटर होने में कोई समस्या नहीं है, क्योंकि उस तर्क का उपयोग केवल उस अधिभार के दौरान किया जाता है जिसके उपयोग के लिए अधिभारित फ़ंक्शन का उपयोग किया जाता है। मैं this संबंधित SO प्रश्न में इन विषयों पर चर्चा करता हूं।

11

जब आप वास्तव में समारोह में पैरामीटर का उपयोग नहीं कर रहे हैं, लेकिन सार्वजनिक विधि हस्ताक्षर तोड़ने के लिए नहीं करना चाहती।

+0

अलेक्जेंड्रोस ने एक बहुत ही अच्छा उदाहरण दिया है (http://stackoverflow.com/questions/3348223/in-c-in-the-definition-of-functions-the-argument-identifiers-are-optional-in/3348345 # 3348345) क्यों आप वास्तविक वस्तु के बारे में परवाह नहीं कर सकते हैं, सिवाय इसके कि यह वहां है। – sbi

0

मुझे लगता है कि आप कार्यों की घोषणा में मतलब है। दरअसल, आप कार्यों की परिभाषा में इंडेंटिफायर नाम को भी छोड़ सकते हैं, लेकिन पैरामीटर का उपयोग होने पर यह संकलन त्रुटि का कारण बन जाएगा, जो होने की संभावना है।

3

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

4

यह कैसे संकलक पोस्टफ़िक्स और उपसर्ग वेतन वृद्धि ऑपरेटरों अलग करता है - एक्स ऑपरेटर ++() है उपसर्ग, एक्स ऑपरेटर ++ (int) पोस्टफ़िक्स है।

क्योंकि पूर्णांक वास्तव में पोस्टफ़िक्स ऑपरेटर में कभी नहीं प्रयोग किया जाता है, वहाँ यह एक नाम देने के लिए कोई कारण नहीं है। यह आम तौर पर दो अलग-अलग चीजों के अर्थ के लिए फ़ंक्शन या ऑपरेटर को अधिभारित करने के लिए, अनाम नाम पैरामीटर क्यों मिलता है। यह लोकी और बूस्ट में उपयोग किए जाने वाले टेम्पलेट मेटाप्रोग्रामिंग में एक आम चाल है।

+0

आप ओपी को यह स्पष्ट करना चाहते हैं कि इसका कारण यह है कि ओवरलोड रिज़ॉल्यूशन की वजह से ... हालांकि मुझे लगता है कि मैंने अभी किया है। –

+0

नहीं, यह नहीं है। ये अलग-अलग हस्ताक्षर हैं, यानी, तर्कों के प्रकार अलग हैं। ओपी क्या पूछ रहा है कुछ पैरामीटर के पहचानकर्ता को छोड़ने के बारे में है। – Juliano

+0

हू? जोएल दिखा रहा है कि एक कंपाइलर एक अज्ञात पैरामीटर का उपयोग कर ++ i और i ++ के बीच कैसे भेदभाव कर सकता है। तुम्हारी किस बारे में बोलने की इच्छा थी? –

1

आप यह कर जब आप कुछ हस्ताक्षर के एक समारोह को लागू कर रहे हैं, वास्तव में पैरामीटर (एक सार के पीछे पदानुक्रम में बहुत आम) की जरूरत नहीं है, और बिना चेतावनी के संकलन करने की जरूरत है। चूंकि सभी परियोजनाओं को चेतावनी मिलने पर तोड़ने के लिए सेट किया जाना चाहिए, और यह ओओपी/जीपी में बहुत कम है, यह एक बहुत ही आम बात है। वास्तव में यह बहुत आम है कि कई पुस्तकालयों में बेहतर सुगमता के लिए एक mylibUNUSED() मैक्रो है।

1

नोट तथ्य यह है कि संकलक वास्तविक पैरामीटर नाम के बारे में परवाह नहीं करता से तथ्य यह है कि आप अलग पैरामीटर नाम एक समारोह (टेम्पलेट) के लिए यह की परिभाषा के लिए की तुलना में की घोषणा का उपयोग कर सकते आता है कि।

यह उपयोगी है जब आपके पास लाइब्रेरी है जिसे आप हेडर के रूप में भेजते हैं और lib फ़ाइल के रूप में और आपके एपीआई का उपयोग करने वाले प्रत्येक व्यक्ति को लाइब्रेरी के अंदर, सबकुछ फिर से संकलित नहीं करना पड़ेगा, आप कुछ के नाम बदलते हैं पैरामीटर (रों)। (शायद आपको इसकी सराहना करने के लिए बहु-एमएलओसी सी ++ प्रोजेक्ट में होना होगा।)

2

अतिरिक्त पैरामीटर का उपयोग SFINAE द्वारा किया जा सकता है, ओवरलोड रिज़ॉल्यूशन या टाइप गुणों के आधार पर प्रेषण के लिए।

#include <boost/utility/enable_if.hpp> 
#include <boost/type_traits.hpp> 
#include <boost/call_traits.hpp> 
#include <iostream> 
#include <string> 

// use SFINAE enable this function for numerical types only 
template <class T> 
double foo(T t, typename 
       boost::enable_if<boost::is_floating_point<T> >:: 
       type* dummy = 0) { 
    double x = static_cast<double>(t); 
    return x; 
} 

// use extra parameter for overload resolution 
struct PlanA {}; 
struct PlanB {}; 

void bar(const PlanA&) { 
    std::cout << "using plan A...\n"; 
} 

void bar(const PlanB&) { 
    std::cout << "using plan B...\n"; 
} 

// use type traits to choose which function to call 
template <typename T> 
double fooBar(T t) { 
    return dispatch(t, boost::is_convertible<T, double>()); 
} 

double dispatch(double t, const boost::true_type&) { 
    std::cout << "convertible to double\n"; 
    return t+0.1; 
} 

template <typename T> 
double dispatch(const T&, const boost::false_type&) { 
    std::cout << "not convertible to double\n"; 
    return 0.0; 
} 


int main() { 

    foo(1.0); 
    // foo(1); won't compile 

    bar(PlanA()); 
    bar(PlanB()); 

    std::string name = "John Dow"; 

    fooBar(1.0); 
    fooBar(name); 
} 
संबंधित मुद्दे