2017-01-12 10 views
7

constexpr functions शामिल करने के लिए नहीं जा सकते:एक कॉन्स्टेक्स फ़ंक्शन में अनुमत क्या है?

गैर शाब्दिक प्रकार

लेकिन इस सवाल का जवाब एक लैम्ब्डा एक में परिभाषित किया गया है में से एक चर की एक परिभाषा: https://stackoverflow.com/a/41616651/2642059

template <typename T> 
constexpr auto make_div(const T quot, const T rem) 
{ 
    return [&]() { 
     decltype(std::div(quot, rem)) result; 
     result.quot = quot; 
     result.rem = rem; 
     return result; 
    }(); 
} 

और मेरी टिप्पणी में मैंने div_t को एक में परिभाषित किया है: How can I Initialize a div_t Object?

template <typename T> 
constexpr decltype(div(T{}, T{})) make_div(const T quot, const T rem) 
{ 
    decltype(div(T{}, T{})) x{}; 
    x.quot = quot; 
    x.rem = rem; 
    return x; 
} 

"गैर-शाब्दिक प्रकार के चर के परिभाषा" के निषेध से क्या मतलब है?

विजुअल स्टूडियो 2015 div_t की मेरी परिभाषा की अनुमति नहीं देगा, लेकिन मुझे यह बकवास लगता है कि यह लैम्ब्डा में इस तरह के अवैध व्यवहार को लपेटने और इसे निष्पादित करने की अनुमति होगी। मैं जानना चाहता हूं कि अगर किसी भी कंपाइलर div_t परिभाषा के संबंध में सही तरीके से व्यवहार कर रहे हैं।

+2

सी ++ भाषा का कौन सा संस्करण? 2011 से आवश्यकताओं को काफी कम किया गया था। – rubenvb

+0

@ रूबेनवब अच्छा सवाल, मैंने संपादित किया है। लेकिन सी ++ 14। –

+4

एक लैम्ब्डा अभिव्यक्ति एक अभिव्यक्ति है, एक चर परिभाषा नहीं है। लेकिन सी ++ 17 तक, एक लैम्ब्डा अभिव्यक्ति एक [निरंतर अभिव्यक्ति] (http://en.cppreference.com/w/cpp/language/constant_expression) में प्रकट नहीं हो सकती है। दरअसल, [जब संदर्भ को निरंतर अभिव्यक्ति की आवश्यकता होती है, तो एमएसवीसी शिकायत करेगा] (http://rextester.com/ZBRLBR12534)। – cpplearner

उत्तर

8

यह वस्तुतः गारंटी है कि एक विसंगति जीसीसी सही व्यवहार है वहाँ है, क्योंकि दृश्य स्टूडियो 2015 constexpr की के विस्तार का समर्थन नहीं करता: https://msdn.microsoft.com/en-us/library/hh567368.aspx#C-14-Core-Language-Features

सी ++ 11 constexpr कार्यों

समारोह शरीर केवल हो सकते हैं:

  • अशक्त बयान (सादा अर्धविराम)
  • static_assert घोषणाओं
  • typedef घोषणाओं और उर्फ ​​घोषणाओं कि वर्ग या enumerations
  • using घोषणाओं
  • using निर्देशों
  • ठीक एक return बयान

तो बर्दाश्त नहीं कर सकते परिभाषित नहीं करतेकी परिभाषा।

template <typename T> 
constexpr auto make_div(const T quot, const T rem) 
{ 
    using foo = decltype(div(T{}, T{})); 

    return foo{1, 0}.quot != 0 ? foo{quot, rem} : foo{rem, quot}; 
} 

Live Example

सी ++ 14 constexpr कार्यों

समारोह शरीर कुछ भी हो सकता है: लेकिन यह रोल करने के लिए एक constexpr समारोह में त्रिगुट सुझाव here एक ही परिणाम प्राप्त करने के लिए स्वीकार्य होगा लेकिन:

    ,210
  • एक एएसएम घोषणा
  • एक गोटो बयान
  • मामले और डिफ़ॉल्ट के अलावा किसी अन्य लेबल के साथ एक बयान
  • एक कोशिश ब्लॉक
  • गैर शाब्दिक प्रकार
  • की एक परिभाषा के एक चर की एक परिभाषा स्थिर या धागा भंडारण अवधि
  • एक चर जिसके लिए कोई प्रारंभ किया जाता है की एक परिभाषा के एक चर

जहां "लिटल टाइप" को here परिभाषित किया गया है, विशेष रूप से ऑब्जेक्ट्स के लिए, वे एक छोटे से विनाशक के साथ कुल प्रकार के हो सकते हैं। तो div_t निश्चित रूप से योग्यता प्राप्त करता है। इस प्रकार , और विस्तार जीसीसी द्वारा, decltype(div(T{}, T{})) x{} की परिभाषा को सहन कर सकते हैं।

सी ++ 17 constexpr कार्यों

सी ++ 17 जोड़ा की "शाब्दिक प्रकार", तो मैं यह अजीब दोनों जीसीसी और दृश्य स्टूडियो में लैम्ब्डा के उपयोग का समर्थन है कि लगता है परिभाषा को बंद करने प्रकार के लिए समर्थन return कथन। मुझे लगता है कि या तो आगे की तलाश में समर्थन है या संकलक ने लैम्ब्डा को रेखांकित करना चुना है। किसी भी मामले में मुझे नहीं लगता कि यह constexpr फ़ंक्शन के रूप में योग्यता प्राप्त करता है।

[Source]

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