दिलचस्प पोस्ट
कॉलबैक फ़ंक्शन को जावास्क्रिप्ट में एक नई विंडो में सेट करें URL से होस्ट डोमेन प्राप्त करें? अनैमिक डोमेन मॉडल: पेशेवरों / विपक्ष किसी यूआरएल के साथ प्रक्षेप में जोड़कर एंजेलरजेएस एकाधिक भाव धराशायी सीमा स्ट्रोक की लंबाई और स्ट्रोक के बीच की दूरी को नियंत्रित करें प्रक्रिया मानक से आउटपुट प्राप्त करेंऑप्टपुट रनटाइम पर सीडी # में पीडीएफ फाइल बनाना ओरेकल: यदि टेबल मौजूद है प्रतिक्रिया में setState Async या सिंक है एएसपी.नेट एमवीसी – क्या व्यापार तर्क नियंत्रकों में मौजूद है? उसी शाखा में दो अलग-अलग कोंट्स के बीच एक ही फाइल को कैसे अलग करना है? एक तत्व के भीतर पाठ की स्थिति प्राप्त करें क्या इंटरफेस बिल्डर से UIView सीमा गुण सेट करना संभव है? टाइप स्क्रिप्ट नियंत्रक और कोणीय जेएस का उपयोग करके डेटा को कैसे बाँटें सी # में प्रतिनिधि प्रतिनिधि

कार्यक्रम को सी ++ में समय संकलित करने पर स्थैतिक एरेज़ बनाएँ

एक संकलित समय पर एक स्थिर सरणी परिभाषित कर सकते हैं:

const std::size_t size = 5; unsigned int list[size] = { 1, 2, 3, 4, 5 }; 

प्रश्न 1 – क्या विभिन्न प्रकार की मेटैप्राग्रामिंग तकनीकों का उपयोग करके इन मूल्यों को "प्रोग्राममैटिक रूप से" समय संकलित करना संभव है?

प्रश्न 2 – सरणी के सभी मानों को मानते हुए एक ही बराबर होना चाहिए, क्या समय-समय पर संकलित कार्यक्रमों में मूल्यों को चुनना संभव है?

उदाहरण के लिए:

 const std::size_t size = 7; unsigned int list[size] = { 0, 0, 2, 3, 0, 0, 0 }; 
  1. सी ++ 0x का उपयोग करने के समाधान का स्वागत है
  2. सरणी बहुत बड़ी हो सकती है, कुछ सौ तत्व लंबे हैं
  3. अब के लिए सरणी में केवल पीओडी प्रकार शामिल होंगे I
  4. यह माना जा सकता है कि सरणी का आकार पहले से एक स्थिर संकलन-समय के अनुरूप तरीके से जाना जाता है।
  5. समाधान C ++ (कोई स्क्रिप्ट, कोई मैक्रोज़, कोई पीपी या कोड जनरेटर आधारित समाधान pls) में होना चाहिए।

अद्यतनः जॉर्ज फ्रिट्ज़ का समाधान अद्भुत है, इसे एमएसवीसी और इंटेल कंपाइलर पर संकलित करने के लिए थोड़ा काम करने की जरूरत है, लेकिन फिर भी इस समस्या के लिए एक बहुत दिलचस्प दृष्टिकोण।

वेब के समाधान से एकत्रित समाधान "कार्यक्रम को सी ++ में समय संकलित करने पर स्थैतिक एरेज़ बनाएँ"

सबसे करीबी आप प्राप्त कर सकते हैं एक variadic टेम्पलेट तर्क सूची से टेम्पलेट के स्थानीय या सदस्य arrays को प्रारंभ करने के लिए C ++ 0x सुविधाओं का उपयोग कर रहा है।
यह निश्चित रूप से अधिकतम टेम्पलेट तत्काल गहराई और मौसम से सीमित होता है जो वास्तव में आपके मामले में उल्लेखनीय अंतर को मापा जाएगा।

उदाहरण:

 template<unsigned... args> struct ArrayHolder { static const unsigned data[sizeof...(args)]; }; template<unsigned... args> const unsigned ArrayHolder<args...>::data[sizeof...(args)] = { args... }; template<size_t N, template<size_t> class F, unsigned... args> struct generate_array_impl { typedef typename generate_array_impl<N-1, F, F<N>::value, args...>::result result; }; template<template<size_t> class F, unsigned... args> struct generate_array_impl<0, F, args...> { typedef ArrayHolder<F<0>::value, args...> result; }; template<size_t N, template<size_t> class F> struct generate_array { typedef typename generate_array_impl<N-1, F>::result result; }; 

आपके 1..5 केस के लिए उपयोग:

 template<size_t index> struct MetaFunc { enum { value = index + 1 }; }; void test() { const size_t count = 5; typedef generate_array<count, MetaFunc>::result A; for (size_t i=0; i<count; ++i) std::cout << A::data[i] << "\n"; } 

अच्छी तरह से आपकी आवश्यकताओं इतनी अस्पष्ट हैं कि उनके बारे में कुछ भी करना मुश्किल है … मुख्य मुद्दा निश्चित रूप से है: ये मूल्य कहां से आता है?

फिर भी सी ++ में एक बिल्ड 4 चरणों के बारे में सोचा जा सकता है:

  • प्री-बिल्ड चरणों: अन्य प्रारूपों से हेडर / स्रोत का स्क्रिप्ट जनरेशन
  • preprocessing
  • टेम्पलेट तत्काल
  • संकलन उचित

यदि आप स्क्रिप्ट पीढ़ी को बाहर करना चाहते हैं, तो आपको 2 विकल्पों के साथ छोड़ दिया गया है: प्रीप्रोसेसिंग और मेटा-टेम्पलेट प्रोग्रामिंग

यहां मेटा-टेम्प्लेट प्रोग्रामिंग के बारे में मुझे पता नहीं कोई तरीका नहीं है, क्योंकि यहां तक ​​कि मुझे पता है कि कंज़ेबल समय में दो सरणियों को जोड़ना संभव नहीं है। इस प्रकार हम दिन के उद्धारकर्ता के साथ रह गए हैं: प्रीप्रोसेसर प्रोग्रामिंग

मुझे हमारी मदद करने के लिए एक पूर्णतया पुस्तकालय का उपयोग करने का सुझाव होगा: बूस्ट । प्रीप्रोसेसर

यहाँ विशेष रुचि का:

  • BOOST_PP_FOR
  • BOOST_PP_REPEAT

अब अगर हमें पता चल गया कि मूल्यों को कहाँ से चुनना है, तो हम और अधिक सार्थक उदाहरण दे सकते हैं।

टेम्पलेट्स का इस्तेमाल करते हुए नेस्टेड स्ट्रेट बनाने के बारे में, और सही प्रकार की एक सरणी के रूप में कास्टिंग। नीचे दिए गए उदाहरण मेरे लिए काम करता है, लेकिन मुझे लग रहा है कि मैं या तो अनिवार्य व्यवहार के चलते चल रहा हूं या बहुत करीब से चल रहा हूं।

 #include <iostream> template<int N> struct NestedStruct { NestedStruct<N-1> contained; int i; NestedStruct<N>() : i(N) {} }; template<> struct NestedStruct<0> { int i; NestedStruct<0>() : i(0) {} }; int main() { NestedStruct<10> f; int *array = reinterpret_cast<int*>(&f); for(unsigned int i=0;i<10;++i) { std::cout<<array[i]<<std::endl; } } 

और निश्चित रूप से आप यह तर्क दे सकते हैं कि कंपाइल समय में सरणी प्रारंभ नहीं की गई है (जो मुझे लगता है कि असंभव है), लेकिन सरणी में जाने वाले मूल्यों को संकलन समय पर गणना की जाती है, और आप उन्हें एक सामान्य सरणी के रूप में एक्सेस कर सकते हैं .. । मुझे लगता है कि जितना करीब आप प्राप्त कर सकते हैं।

क्या आप वास्तव में इसे संकलक समय पर करने की ज़रूरत है? यह स्थिर प्रारंभिक समय पर करना बहुत आसान होगा आप ऐसा कुछ कर सकते हैं

 #include <cstddef> #include <algorithm> template<std::size_t n> struct Sequence { int list[n]; Sequence() { for (std::size_t m = 0; m != n; ++m) { list[m] = m + 1; } } }; const Sequence<5> seq1; struct MostlyZero { int list[5]; MostlyZero() { std::fill_n(list, 5, 0); // Not actually necessary if our only // are static as static objects are // always zero-initialized before any // other initialization list[2] = 2; list[3] = 3; } }; const MostlyZero mz1; #include <iostream> #include <ostream> int main() { for (std::size_t n = 0; n != 5; ++n) { std::cout << seq1.list[n] << ", " << mz1.list[n] << '\n'; } } 

यदि आप चाहें तो आप सूचियों के बाहर सूचियों को धक्का दे सकते हैं, लेकिन मैंने सोचा था कि यह इस तरह की क्लीनर था।

कुछ बूस्ट की तरह। असाइनमेंट मानक कंटेनर के लिए काम कर सकता है यदि आपको वास्तव में सरणियों का उपयोग करना है, तो आप इसे बूस्ट के साथ उपयोग कर सकते हैं। अर्रे

कुछ समय (हमेशा नहीं) ऐसी सरणी प्रकार के सरणी से उत्पन्न होती है। उदाहरण के लिए यदि आपके पास पहले से भेदभाविक वर्ग सूची (जैसे टेम्पलेट) है और आप इनकैप्सेटिल्ट यूआईटी 32_टी मूल्य को उपयोग कर सकते हैं जिसे आप उपयोग कर सकते हैं:

 uint32_t tab[sizeof(A)]= {A::value...}; 

1't प्रश्न आप ऐसा कर सकते हैं

 template <int num, int cur> struct ConsequentListInternal { enum {value = cur}; ConsequentListInternal<num-1,cur+1> next_elem; }; template <int cur> struct ConsequentListInternal<0, cur> { enum {value = cur}; }; template <int v> struct ConsequentList { ConsequentListInternal<v, 0> list; }; int main() { ConsequentList<15> list; return 0; } 

बहुत सी चीजें हैं जो आप मेटा-प्रोग्रामिंग के साथ कर सकते हैं लेकिन पहले मैं पूछना चाहता हूं: आप इसे अपने मामले में क्यों करना चाहते हैं? मैं समझ सकता था कि आपको अलग-अलग जगहों में इस तरह के सरणी को घोषित करने की आवश्यकता है, ताकि वह एक ही चीज़ को कई बार दोबारा लिखने की मांग कर सके। क्या यह तुम्हारा मामला है?

"प्रोग्राम को परिभाषित करें" कहकर मैं निम्नलिखित सुझाव देता हूं:

 #define MyArr(macro, sep) \ macro(0) sep \ macro(0) sep \ macro(2) sep \ macro(3) sep \ macro(0) sep \ macro(0) sep \ macro(0) 

अब तक हमने उन सभी मूल्यों को परिभाषित किया है जिन्हें आप चाहते थे कि वे सबसे अमूर्त तरीके से। बीटीडब्ल्यू यदि उन मानों का वास्तव में आप के लिए कुछ मतलब है – आप इसे घोषणा में जोड़ सकते हैं:

 #define MyArr(macro, sep) \ macro(0, Something1) sep \ macro(0, Something2) sep \ // ... 

अब चलो सांस जीवन ऊपर घोषणा में जीवन।

 #define NOP #define COMMA , #define Macro_Count(num, descr) 1 #define Macro_Value(num, descr) num const std::size_t size = MyArr(Macro_Count, +); unsigned int list[size] = { MyArr(Macro_Value, COMMA) }; 

आप ऐसी परिस्थिति को भी संभाल सकते हैं जहां आपकी अधिकांश प्रविष्टियां एक समान होती हैं, कुछ विकृत रचनात्मकता के साथ 🙂

लेकिन आपको हमेशा खुद से पूछना चाहिए: क्या यह वास्तव में इसके लायक है? क्योंकि, जैसा कि आप देख सकते हैं, आप कोड को पहेली में बदल देते हैं।

बढ़ावा देने से,

 boost::mpl::range_c<int,1,5> 

संकलन के समय में क्रमबद्ध संख्याओं की सूची 1 से 5 से उत्पन्न होगी। दूसरे के लिए, आप कोई मानदंड नहीं बताते हैं, जिसके लिए मूल्य बदल जाएगा। मुझे पूरा यकीन है कि आप एक सूची बनाते समय एक नए वर्जन को फिर से नहीं बदल सकते हैं।

सिर्फ एक कोड जनरेटर का उपयोग करें एक या अधिक टेम्पलेट बनाएं, जो कि आप चाहते हैं कोड बना सकते हैं, तालिका का उपयोग कर सकते हैं या यहां तक ​​कि गणित फ़ंक्शन भी। फिर अपने ऐप में जेनरेट की गई फ़ाइल को शामिल करें

सच में, एक कोड जनरेटर आपके जीवन को बहुत आसान बना देगा