2015-09-04 7 views
5

मैं क्या समझ से, एक constexpr समारोह पूरे मूल्यांकन संकलन समय पर किया जा सकता है, तो या नहीं पर निर्भर करता है, संकलन समय के साथ-साथ कार्यावधि में क्रियान्वित किया जा सकता।मैं एक constexpr फ़ंक्शन में रनटाइम जोर कैसे दे सकता हूं?

हालांकि, आप इस समारोह को ओवरलोड नहीं कर सकते एक क्रम है और एक संकलन समय समकक्ष है।

तो मेरे सवाल है, मैं एक क्रम दर्शाते हैं उनमें कैसे डाल सुनिश्चित करना है कि क्रम समारोह के निष्पादन मेरी static_assert के साथ वैध पैरामीटर पारित हो जाता है कर सकते हैं?

उत्तर

4

एरिक Niebler Assert and Constexpr in C++11 में अच्छी तरह से इस मुद्दे को शामिल किया गया, वह बताते हैं कि एक constexpr समारोह में जोर का उपयोग की अनुमति नहीं है सी ++ 11 लेकिन यह सी ++ 14 (As part of the Relaxing constraints on constexpr functions proposal) में अनुमति दी और निम्नलिखित स्निपेट प्रदान करे:

constexpr bool in_range(int val, int min, int max) 
{ 
    assert(min <= max); // OOPS, not constexpr 
    return min <= val && val <= max; 
} 

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

वह कुछ विकल्प का सुझाव:

  1. noexcept specifier साथ फेंक का उपयोग करना: एक अपवाद समारोह एसटीडी छोड़ देता है

    constexpr bool in_range(int val, int min, int max) noexcept 
    { 
        return (min <= max) 
        ? min <= val && val <= max 
        : throw std::logic_error("Assertion failed!"); 
    } 
    

    अगर :: समाप्त बुलाया जाएगा। एक अपवाद प्रकार के निर्माता से

  2. कॉल std::quick_exit:

    constexpr bool in_range(int val, int min, int max) 
    { 
        return (min <= max) 
         ? min <= val && val <= max 
         : throw assert_failure(
          []{assert(!"input not in range");} 
         ); 
    } 
    
+0

मैं भी कर दिया है:

struct assert_failure { explicit assert_failure(const char *sz) { std::fprintf(stderr, "Assertion failure: %s\n", sz); std::quick_exit(EXIT_FAILURE); } }; constexpr bool in_range(int val, int min, int max) { return (min <= max) ? min <= val && val <= max : throw assert_failure("min > max!"); } 
  • एक लैम्ब्डा अभिव्यक्ति है कि एक अपवाद प्रकार के निर्माता को इस बात पर ज़ोर दर्रा पता चला है कि आप सूची सूची में सीधे जोर दे सकते हैं। 'constexpr bool in_range (int val, int min, int max) {वापसी (जोर दें (न्यूनतम <= अधिकतम), न्यूनतम <= val && val <= max); } 'मूल रूप से, आप इसे बनाने के लिए इतना है कि यह गैर constexpr कॉल करने के लिए करता है, तो असफलता पर एक constexpr संदर्भ में इस्तेमाल कभी नहीं प्राप्त कर सकते हैं। यह काम करता है क्योंकि, जोर एक टर्नरी अभिव्यक्ति के लिए एक मैक्रो है, जो विफलता पर अंतर्निहित गैर-कॉन्स्टेक्सर फ़ंक्शन को कॉल करने का मूल्यांकन करता है। – Adrian

  • +0

    @ एड्रियन दिलचस्प है कि [कॉमा ऑपरेटर को केवल सी ++ 11 में निरंतर अभिव्यक्तियों में अनुमति दी गई थी] (http://stackoverflow.com/q/27324573/1708801)। –

    +0

    @ एड्रियन हालांकि यह पोर्टेबल नहीं होगा क्योंकि यह 'assert' के कार्यान्वयन विवरण पर निर्भर करता है जो मानक द्वारा कवर नहीं है। –

    1

    आप एक अपवाद फेंक कर सकते हैं। यदि एक कॉन्स्टेक्स फ़ंक्शन से संकलन समय पर एक अपवाद फेंक दिया जाता है, तो यह मूल रूप से एक स्थिर जोर देने में विफल होने की गणना करता है। यदि यह रनटाइम पर होता है, तो यह सामान्य रूप से अपवाद होगा। Passing constexpr objects around

    भी संबंधित हैं::

    यह सवाल एक कोड उदाहरण है, जहां ऐसा होता है पता चलता What happens when an exception is thrown while computing a constexpr?

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