2015-11-15 9 views
6

मानकों कागज P0092R1, हावर्ड Hinnant में लिखा है:यह कोड कैसे समेकित हो सकता है? (Std :: chrono)

template <class To, class Rep, class Period, 
      class = enable_if_t<detail::is_duration<To>{}>> 
constexpr 
To floor(const duration<Rep, Period>& d) 
{ 
    To t = duration_cast<To>(d); 
    if (t > d) 
     --t; 
    return t; 
} 

कैसे इस कोड को काम कर सकते हैं? समस्या यह है कि operator--std::chrono::duration पर एक कॉन्स्टेक्स ऑपरेशन नहीं है। यह रूप में परिभाषित किया गया है:

duration& operator--(); 

और फिर भी इस कोड को संकलित करता है, और संकलन समय पर सही जवाब देता है:

static_assert(floor<hours>(minutes{3}).count() == 0, "”); 

कि के साथ क्या है?

+0

हावर्ड के पेपर का मूल संस्करण (पी 0) एफडब्ल्यूआईडब्ल्यू यहां उपलब्ध है: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0092r0.html –

उत्तर

9

उत्तर यह है कि संकलन-समय के दिनचर्या में सभी परिचालनों को समेकित नहीं होना चाहिए; केवल जिन्हें संकलित समय पर निष्पादित किया गया है।

उदाहरण में ऊपर, संचालन कर रहे हैं:

hours t = duration_cast<hours>(d); 
if (t > d) {} // which is false, so execution skips the block 
return t; 

जो सभी संकलन समय पर किया जा सकता है।

दूसरी ओर, तुम कोशिश कर रहे थे, तो:

static_assert(floor<hours>(minutes{-3}).count() == -1, "”); 

यह एक संकलन समय त्रुटि कह देना होगा (बजना का उपयोग कर):

error: static_assert expression is not an integral constant expression 
     static_assert(floor<hours>(minutes{-3}).count() == -1, ""); 
         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
note: non-constexpr function 'operator--' cannot be used in a constant expression 
         --t; 
         ^
note: in call to 'floor(minutes{-3})' 
     static_assert(floor<hours>(minutes{-3}).count() == -1, ""); 

जब constexpr कोड लिखने, आप कोड के माध्यम से सभी पथ पर विचार करना होगा।

पीएस आप प्रस्तावित floor दिनचर्या thusly ठीक कर सकते हैं:

template <class To, class Rep, class Period, 
      class = enable_if_t<detail::is_duration<To>{}>> 
constexpr 
To floor(const duration<Rep, Period>& d) 
{ 
    To t = duration_cast<To>(d); 
    if (t > d) 
     t = t - To{1}; 
    return t; 
} 
0

n3597 और n3652 के नियमों के तहत, एक constexpr समारोह अंदर भाव खुद को, निरंतर भाव होने के लिए जब तक वे विश्व स्तर पर दिखाई राज्य को संशोधित नहीं की जरूरत नहीं है।

constexpr int f(int a) { 
    int n = a; 
    ++n;     // '++n' is not a constant expression 
    return n * a; 
} 
int k = f(4);   // OK, this is a constant expression. 
         // 'n' in 'f' can be modified because its lifetime 
         // began during the evaluation of the expression. 

का एक उदाहरण है सबसे अधिक संभावना है कि इन नियमों हावर्ड Hinnant पीछा किया जब कागज आप का उल्लेख लेखन कर रहे हैं।

प्रश्न में duration<T> कोड के साथ काम करने के लिए, operator-- को constexpr फ़ंक्शन बनाया जाना होगा। चूंकि लाइब्रेरी में constexpr परिवर्तन अंतिम नहीं थे, इसलिए यह समझना आसान है कि हॉवर्ड इस तरह के परिवर्तन पर कैसे निर्भर हो सकता था।

+2

क्षमा करें बेन, मार्शल यह एक बिल्कुल सही है। आपके द्वारा उल्लेख किए गए कागजात सी ++ 14 में हैं, और मैंने सी ++ 14 का उपयोग करके हाल ही में यह त्रुटि बनाई है। –

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