c++ - Constexpr wrapper over C array with std::vector-like constructors -


मुझे कुछ अतिरिक्त कन्स्ट्रक्टरों के साथ एक सी सरणी या एक std :: array पर एक constexpr wrapper की आवश्यकता है ( std :: vector कन्स्ट्रक्टर के समान):

  टेम्पलेट & lt; class T, int N & gt; संरचना आवरण {टी डेटा [एन]; Constexpr आवरण (int s); // एक स्थिर आवरण (int j, int k); // ब constexpr आवरण (... मूल्यों ...) / / c: डेटा (... मूल्य ...) {}};   

मैं std :: vector कन्स्ट्रक्टर के समान व्यवहार प्राप्त करने का प्रयास कर रहा हूं, जो है:

  constexpr wrapper & lt; टी, 2 & gt; डब्ल्यू (1); // एक constexpr wrapper & lt; T, 2 & gt; डब्ल्यू (1,2); // कॉल b constexpr आवरण & lt; टी, 2 & gt; w {1}; // कॉल सी constexpr आवरण & lt; टी, 2 & gt; w {1,2}; // कॉल सी   

नोट 1: एक सही फ़ॉरवर्डिंग कन्स्ट्रक्टर:

  टेम्पलेट & lt; class ... args & gt; (एसटीडी :: फॉरवर्ड & lt; T & gt; (टी), std :: forward & lt; एआरजेस & gt; (आरजीएस) ...) {}  

नोट 2: टी [एन] / एसटीडी :: एरे & lt; T, N & gt; नहीं है < कोड> std :: initializer_list & lt; T & gt; कन्स्ट्रक्टर ताकि निम्न काम न हो:

  constexpr आवरण (std :: initializer_list & lt; T & gt; v): डेटा (std: नोट: यदि कोई कंस्ट्रक्टर आरंभीकरण सूची में मान को असाइन नहीं किया जाता है तो रैपर प्रकार निरंतर अभिव्यक्ति में काम नहीं करेगा    

Div>

ज़रूर, बस index_sequence और एक प्रतिनिधि कर्ता का प्रयोग करें:

  Constexpr wrapper (std :: initializer_list & lt; T & gt; v): आवरण (std :: make_index_sequence & lt; N & gt; {}, v) {} निजी: टेम्पलेट & lt; std :: size_t ... is & gt; Constexpr wrapper (std :: index_sequence & lt; is ... & gt ;, std :: initializer_list & lt; टी & gt; v): डेटा {v.begin () [है] ...} {}   < P> यह  [support.initlist.access]  के  initializer_list  के एक्सेसर्स के कारण  constexpr  है, क्योंकि यह काम करता है; इसके इटरेटर प्रकार  ई const *  है, इसलिए हम समय को संकलित करने पर अपनी सरणी के किसी भी परिभाषित सदस्य का उपयोग कर सकते हैं।  

ध्यान दें कि यदि आप बहुत-छोटी ब्रैकेट-इन-लिस्ट की आपूर्ति करते हैं ( जैसे कि v.size () & lt; N ) तो यह विफल हो जाएगा; समय का संकलन करने पर, यदि निरंतर अभिव्यक्ति में प्रयोग किया जाता है, और अन्यथा अनिर्धारित व्यवहार के साथ। यहां एक समाधान है, डिफ़ॉल्ट-निर्माण T यदि अनुमति है, और एक अपवाद अन्यथा फेंक रहा है:

  constexpr स्थिर टी too_short (std :: true_type) {return {}; } टी too_short (std :: false_type) {std :: invalid_argument को फेंकें ("ब्रेसेड-इनिट-सूची बहुत छोटी"); } टेम्पलेट & lt; std :: size_t ... है & gt; Constexpr आवरण (std :: index_sequence & lt; is ... & gt ;, std :: initializer_list & lt; T & gt; v): डेटा {v.size () & gt; है ? V.begin () [है]: too_short (std :: is_default_constructible & lt; T & gt; {}) ...} {}   

बहुत कम ब्रैकेट-इनिट-लिस्ट, फेंक-अभिव्यक्ति के साथ सशर्त ऑपरेटर की दाईं ओर की जगह को बदलें:

  constexpr आवरण (std :: initializer_list & lt; T & gt; v): आवरण (Std :: make_index_sequence & lt; N & gt; {}, v.size () == एन? वी: स्टड :: अमान्य_गार्मन ("ब्रेसिड-इनिट-लिस्ट ग़लत लंबाई")) {} निजी: टेम्पलेट & lt; std :: size_t .. है & gt; Constexpr wrapper (std :: index_sequence & lt; is ... & gt ;, std :: initializer_list & lt; टी & gt; v): डेटा {v.begin () [है] ...} {}   < P> यह समय के संकलन में पता लगाने के लिए निरंतर अभिव्यक्ति के अलावा अन्य संभव नहीं है, जो ब्रैकेट-इनिट-सूची बहुत छोटा है (या बहुत लंबा!), क्योंकि  initializer_list  छुपाती है प्रकार सिस्टम।  



Comments

Popular posts from this blog

java - ImportError: No module named py4j.java_gateway -

python - Receiving "KeyError" after decoding json result from url -

.net - Creating a new Queue Manager and Queue in Websphere MQ (using C#) -