2010-08-08 17 views
11

निम्नलिखित स्निपेट पर विचार से लौट रहे:सी में एक शून्य समारोह ++

void Foo() 
{ 
    // ... 
} 

void Bar() 
{ 
    return Foo(); 
} 

क्या C++ में ऊपर का उपयोग करने के रूप में अधिक आम दृष्टिकोण का विरोध करने के लिए एक वैध कारण है:

void Foo() 
{ 
    // ... 
} 

void Bar() 
{ 
    Foo(); 

    // no more expressions -- i.e., implicit return here 
} 

उत्तर

16

शायद आपके उदाहरण में कोई उपयोग नहीं है, लेकिन कुछ स्थितियां हैं जहां टेम्पलेट कोड में void से निपटना मुश्किल है, और मुझे उम्मीद है कि यह नियम कभी-कभी उसमें सहायता करता है। बहुत काल्पनिक उदाहरण:

#include <iostream> 

template <typename T> 
T retval() { 
    return T(); 
} 

template <> 
void retval() { 
    return; 
} 

template <> 
int retval() { 
    return 23; 
} 

template <typename T> 
T do_something() { 
    std::cout << "doing something\n"; 
} 

template <typename T> 
T do_something_and_return() { 
    do_something<T>(); 
    return retval<T>(); 
} 

int main() { 
    std::cout << do_something_and_return<int>() << "\n"; 
    std::cout << do_something_and_return<void*>() << "\n"; 
    do_something_and_return<void>(); 
} 

ध्यान दें कि केवल main तथ्य void मामले में retval से लौटने की कोई बात नहीं है कि से निपटने के लिए है। इंटरमीडिएट फ़ंक्शन do_something_and_return सामान्य है।

बेशक यह आपको केवल इतना ही प्राप्त करता है - अगर do_something_and_return सामान्य स्थिति में retval को एक चर में संग्रहीत करने और लौटने से पहले इसके साथ कुछ करने के लिए चाहते थे, तो आप अभी भी परेशानी में होंगे - आपको शून्य के लिए do_something_and_return विशेषज्ञ (या अधिभार)।

+0

धन्यवाद। सभी जवाब अच्छे थे, लेकिन इसने इस बिंदु को अच्छी तरह से चित्रित किया। – kirk0

0

केवल कारण मैं सोच सकता हूं कि यदि आपके पास स्विच में कथन की लंबी सूची थी और इसे और अधिक कॉम्पैक्ट बनाना चाहता था।

9

यह एक बेकार निर्माण है जो किसी उद्देश्य का कार्य नहीं करता है, जब तक कि इसका उपयोग टेम्पलेट्स के साथ नहीं किया जाता। यही है, यदि आपने टेम्पलेट फ़ंक्शंस को परिभाषित किया है जो एक मान देता है जो 'शून्य' हो सकता है।

+4

तो यह शायद ही कभी "बेकार" है, है ना? ;) – jalf

+0

@jalf: ठीक है, इस रूप में यह सवाल में दिखाया गया है कि यह बहुत बेकार है, है ना? ;-) –

+0

पर्याप्त सच है। मैंने भाषा में सुविधा के उदाहरण के रूप में प्रश्न में कोड का अर्थ दिया, और पूछताछ की कि भाषा सामान्य * सामान्य * कब उपयोगी है। लेकिन उचित बिंदु। ;) – jalf

7

आप इसे सामान्य कोड में उपयोग करेंगे, जहां Foo() का वापसी मूल्य अज्ञात है या परिवर्तन के अधीन है। विचार करें:

template<typename Foo, typename T> T Bar(Foo f) { 
    return f(); 
} 

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

इसके अलावा, स्पष्ट रूप से लौटने के लिए एक अच्छी आदत है।

4

टेम्पलेट:

template <typename T, typename R> 
R some_kind_of_wrapper(R (*func)(T), T t) 
{ 
    /* Do something interesting to t */ 
    return func(t); 
} 

int func1(int i) { /* ... */ return i; } 

void func2(const std::string& str) { /* ... */ } 

int main() 
{ 
    int i = some_kind_of_wrapper(&func1, 42); 

    some_kind_of_wrapper(&func2, "Hello, World!"); 

    return 0; 
} 

शून्य वापस जाने के लिए सक्षम किया जा रहा बिना, टेम्पलेट में return func(t) कार्य नहीं करेगा जब यह func2 रैप करने के लिए कहा गया था।

0

कारण math.h जैसी स्मृति लौटा रहा है हमेशा देता है। math.h में कोई शून्य नहीं है और कोई खाली तर्क नहीं है। ऐसी कई व्यावहारिक स्थितियां हैं जहां आपको स्मृति की आवश्यकता है।

+0

क्या?गणित कार्य तर्क लेते हैं और मान वापस करते हैं क्योंकि गणित कार्यों के लिए उन्हें यही करने की आवश्यकता होती है ... – GManNickG

0

एक ऐसा मामला हो सकता है जहां Foo() मूल रूप से एक मान लौटा, लेकिन बाद में इसे void में बदल दिया गया, और जिस व्यक्ति ने इसे अपडेट किया वह बहुत स्पष्ट रूप से नहीं सोचा था।

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