2016-05-19 8 views
57

सी ++ में एक डिफ़ॉल्ट तर्क के लिए, क्या मान स्थिर होना चाहिए या कोई अन्य तर्क होगा?क्या एक सी ++ डिफ़ॉल्ट तर्क दूसरे तर्क के साथ आरंभ किया जा सकता है?

क्या यह निम्नलिखित कार्य कर सकता है?

RateLimiter.h:13: error: ‘rateInPermitsPerSecond’ was not declared in this scope

+4

@ बाममितएगेन सुंदर निर्णायक नहीं है? –

+0

@ रिचर्डहोजेस हाँ, संकलक यहां पैसे पर सही था। –

+1

मैं एक तार्किक स्पष्टीकरण की तलाश में था कि इसकी अनुमति क्यों नहीं है। – user1918858

उत्तर

78

एक और तर्क है डिफ़ॉल्ट मान के रूप में इस्तेमाल नहीं किया जा सकता:

RateLimiter(unsigned double rateInPermitsPerSecond, 
      unsigned int maxAccumulatedPermits = rateInPermitsPerSecond); 

वर्तमान में मैं एक त्रुटि हो रही है। मानक कहता है:

8.3.6 Default arguments
...
9 A default argument is evaluated each time the function is called with no argument for the corresponding parameter. The order of evaluation of function arguments is unspecified. Consequently, parameters of a function shall not be used in a default argument, even if they are not evaluated.

और निम्न नमूना के साथ यह दिखाता है:

int f(int a, int b = a); // error: parameter a 
         // used as default argument 
70

नहीं, यह है क्योंकि समारोह तर्क के मूल्यांकन अनुक्रम नहीं है काम नहीं कर सकता। यह भी काम नहीं करता है क्योंकि मानक इसे अनुमति नहीं देता है, लेकिन मुझे लगता है कि यह स्पष्ट था।

उपयोग एक अधिभार के बजाय:

void fun(int, int) {} 

void fun(int i) { 
    fun(i, i); 
} 
36

I was looking for an logical explanation for why it is not allowed

यह वास्तव में एक अच्छा सवाल है। कारण यह है कि सी ++ तर्कों के मूल्यांकन के आदेश को अनिवार्य नहीं करता है।

int f(int a, int b = ++a); 

... followed by ... 

int a = 1; 
f(a); 

सी ++, याद तर्क के मूल्यांकन के आदेश जनादेश नहीं करता है:

तो चलो एक थोड़ा और अधिक जटिल परिदृश्य की कल्पना करते हैं?

तो बी का मूल्य क्या होना चाहिए?

f(a) मूल्यांकन कर सकते हैं करने के लिए या तो:

f(1, 2), या f(2, 2), तर्क के मूल्यांकन के आदेश पर निर्भर करता है।

इस प्रकार व्यवहार अपरिभाषित (और यहां तक ​​कि अनिश्चित) भी होगा।

आगे, विचार करें कि क्या हो सकता है जब ए और बी जटिल वस्तुएं थीं जिनके रचनाकारों और प्रतिलिपि ऑपरेटरों के दुष्प्रभाव थे।

उन दुष्प्रभावों का क्रम अपरिभाषित होगा।

+1

अच्छा उदाहरण ... int f के बारे में क्या (int a = b ++, int b = a ++); मुझे इसकी आवश्यकता है कि एक फैंसी मृत लूप – Mzn

+4

@Mzn अपरिभाषित व्यवहार अगर यह कानूनी था, जो यह नहीं है। –

11

आप ऐसी चीजें नहीं कर सकते क्योंकि मानक इसे अनुमति नहीं देता है। के रूप में (भाषा ने सुझाव दिया "

void RateLimiter(unsigned int rateInPermitsPerSecond, 
       unsigned int maxAccumulatedPermits); 

inline void RateLimiter(unsigned int rateInPermitsPerSecond) 
{ return RateLimiter(rateInPermitsPerSecond,rateInPermitsPerSecond); } 

यह दिखाता है कि मानक इस मना, अधूरे मन से है: लेकिन जब से डिफ़ॉल्ट तर्क को प्रभावी ढंग से सिर्फ नए कार्य भार के परिभाषित करते हैं, आप स्पष्ट रूप से इस तरह के एक अधिभार को परिभाषित करते हुए वांछित प्रभाव प्राप्त कर सकते हैं नतीजतन ... नहीं होगा ... ")। वे स्पष्ट रूप से इस प्रभाव के साथ परिभाषित करने की परेशानी से गुजरना नहीं चाहते थे कि स्पष्ट अधिभार घोषणा क्या होगी: यदि वांछित है, तो वे निर्दिष्ट कर सकते थे कि डिफ़ॉल्ट रूप से प्रदान किए गए तर्कों के बाद डिफ़ॉल्ट तर्कों का मूल्यांकन किया जाता है, और बाएं से दाएं ।इस नियम पर इसका कोई प्रभाव नहीं होगा कि फ़ंक्शन कॉल में तर्क अभिव्यक्तियों का मूल्यांकन क्रम निर्दिष्ट नहीं है (क्योंकि डिफ़ॉल्ट तर्क ऐसे अभिव्यक्तियों के अनुरूप नहीं होते हैं; वे पूरी तरह से अलग हैं और समान व्याख्यात्मक दायरे में भी नहीं)। दूसरी तरफ अगर (जैसा उन्होंने किया) वे इसे अस्वीकार करना पसंद करते थे, तो वे सिर्फ कुछ अन्य नियमों से खुद को औचित्य देने की आवश्यकता के बिना "नहीं" कह सकते थे (लेकिन शायद व्याख्यात्मक फुटनोट के साथ)।

2

For a default argument in C++, does the value need to be a constant or will another argument do?

तर्क का डिफ़ॉल्ट मान एक और तर्क नहीं हो सकता है। हालांकि, इसका मतलब यह नहीं है कि इसे स्थिर होना चाहिए। यह फ़ंक्शन कॉल का रिटर्न वैल्यू हो सकता है।

int getNextDefaultID() 
{ 
    static int id = 0; 
    return ++id; 
} 

struct Foo 
{ 
    Foo(int data, int id = getNextDefaultID()) : data_(data), id_(id) {} 
    int data_; 
    int id_; 
}; 

int main() 
{ 
    Foo f1(10);  // Gets the next default ID. 
    Foo f2(20, 999); // ID is specified. 
} 
संबंधित मुद्दे