2012-09-11 10 views
6

मैं डी भाषा में टेम्पलेट सिस्टम के बारे में पढ़ रहा हूं और असामान्य निर्माण पर आया, static ifडी में स्थिर क्यों उपयोग करें?

जो मैं समझने में कामयाब रहा उससे इसे संकलित समय पर मूल्यांकन किया जाता है, लेकिन जो मैंने खोजा है, उदाहरण दिखाया गया है कि here ने मुझे काफी प्रबुद्ध नहीं किया।

template Factorial(ulong n) 
{ 
    static if(n < 2) 
     const Factorial = 1; 
    else 
     const Factorial = n * Factorial!(n - 1); 
} 

static if क्या करता है, और मुझे इसका उपयोग कब करना चाहिए?

+0

नहीं मिला वास्तव में आप क्या उम्मीद कर रहे हैं, कृपया समस्या का विस्तार करें –

+3

यह कैसे सी ++ टैग किया गया है? –

+0

@ आर। मार्टिनो फर्नांडीस जो मुझे पता है उससे सी ++ – coredump

उत्तर

11

डी static if "सशर्त संकलन" का आधार है, और एक महत्वपूर्ण भूमिका निभाता है जहां एक कोड के एक संस्करण के बारे में संकलन समय निर्णय लिया जाना चाहिए।

के बाद से विकास एक पूर्वप्रक्रमक नहीं है, बातें

#ifdef xxx 
compile_this_piece_of_code 
#endif 

तरह बन सकता

static if(xxx) 
{ 
    compile_this_pece_of_code 
} 

इसी तरह, metaprogramming के माध्यम से स्थिर है, तो भी हो सकता है:

template<int x> 
struct traits 
{ some definition calculated from x }; 

template<> 
struct traits<0> 
{ same definitions for the 0 particular case } 

हो सकता है

template(int x) 
{ 
    static if(x==0) 
    { some definitions } 
    else 
    { some other same definitions } 
    even more definition common in the two cases 
} 
+0

धन्यवाद। मुझे लगता है कि मुझे उलझन में क्या काम था। – coredump

+0

बीटीडब्ल्यू। पहला उदाहरण संकलित नहीं होगा। उस डी के लिए 'संस्करण (XXX) {} और {} ' – DejanLekic

+1

है यह वास्तव में xxx पर निर्भर करता है: यदि यह प्रतीक है, तो संस्करण कथन है, यदि यह स्थिर अभिव्यक्ति static_if काम करता है। सही उदाहरण सबसे अधिक संभावना नहीं है '#ifdef ...' लेकिन '#if ....' –

3

विकिपीडिया उदाहरण वास्तव में बहुत सरल है:

template Factorial(ulong n) 
{ 
    static if(n < 2) 
     const Factorial = 1; 
    else 
     const Factorial = n * Factorial!(n - 1); 
} 

यह एक विशिष्ट व्यक्ति-विषयक टेम्पलेट (नीचे जोनाथन की टिप्पणी देखें)। n टेम्पलेट पैरामीटर है। तो, यदि आपने इसके बजाय लिखा था:

template Factorial(ulong n) 
{ 
    if(n < 2) // NOTE: no static here 
     const Factorial = 1; 
    else 
     const Factorial = n * Factorial!(n - 1); 
} 

? - यह काम नहीं करेगा। http://dpaste.dzfl.pl/3fe074f2 देखें। कारण यह तथ्य है कि अगर स्थिर और "सामान्य" अलग-अलग अर्थशास्त्र हैं। static if एक असाइनमेंट अभिव्यक्ति लेता है (http://dlang.org/version.html, खंड "स्टेटिक अगर") जिसका मूल्यांकन संकलित समय पर किया जाता है, जबकि सामान्य अगर रन-टाइम पर मूल्यांकन किया जाता है तो सामान्य होता है।

Static if एमिलियो द्वारा वर्णित "सशर्त संकलन" करने का एक ही तरीका है। डी में version कीवर्ड भी है। तो एमिलियो का पहला सशर्त संकलन उदाहरण (जो डी में काम नहीं करता है) की तरह कुछ हो जाता है:

version (XXX) { 
    // XXX defined 
} else { 
    // XXX not defined 
} 

आप अगर इस के लिए, आप की तरह कुछ लिखते थे स्थिर उपयोग करना चाहते हैं:

enum int XXX = 10; 
static if (XXX == 10) { 
    pragma(msg, "ten"); 
} 
+3

फैक्टोरियल टेम्पलेट फ़ंक्शन नहीं है। यह एक उपनाम टेम्पलेट है। टेम्पलेट का उपयोग टेम्पलेट के परिणाम के साथ बदल दिया गया है जो टेम्पलेट के समान टेम्पलेट के समान प्रतीक है - उदा। 'फैक्टोरियल! 5' '120' बन जाता है। यह पूरी तरह से एक संकलन समय निर्माण है। यह एक टेम्पलेटेड फ़ंक्शन से पूरी तरह से अलग है जिसे किसी अन्य फ़ंक्शन की तरह कहा जाता है लेकिन इसके तर्कों के प्रकार के आधार पर अलग-अलग के साथ तत्काल प्रारंभ किया जाता है। आपके उत्तर के आधार पर, मैं अनुमान लगा रहा हूं कि आप इसे समझते हैं और केवल शब्दावली गलत है, लेकिन आप भ्रम पैदा करने जा रहे हैं। –

+0

सही। :) मैं अपना जवाब अपडेट करने जा रहा हूं ताकि शब्दावली सही हो। – DejanLekic

3

आंद्रेई Alexandrescu एक अच्छी बात है कि यदि आप एक सी ++ संदर्भ में (यदि आप यही पूछ रहे हैं) में स्थिर के बारे में यहां देख सकते हैं।

लिंक: http://channel9.msdn.com/Events/GoingNative/GoingNative-2012/Static-If-I-Had-a-Hammer

लघु जवाब- यह कुछ एक बहुत अधिक सहज ज्ञान युक्त metaprogramming टेम्पलेट के लिए वाक्य रचना बनाता है।

+0

वाल्टर ने अपनी प्रस्तुतियों में से एक में 'स्थिर' को भी छुआ, मैं बस भूल गया ... :) – DejanLekic

0

एंड्री अलेक्जेंड्रेस्कू हाल ही में कुछ महान उदाहरणों (video, slides) के साथ static if "इंट्रोस्पेक्शन द्वारा डिज़ाइन" का स्मार्ट उपयोग कॉल कर रहा है।

उनकी बात से एक सीधा उदाहरण रॉबिन हूड हैशिंग का उपयोग करके एक हैश टेबल जैसे सामान्य कंटेनर को कार्यान्वित करेगा, जहां तालिका में प्रत्येक प्रविष्टि के साथ एक अतिरिक्त डेटा (जांच गिनती) रखी जाती है। static if के साथ हम जांच गिनती अपने संरेखण के आधार पर कुंजी के बगल में रखकर स्वचालित रूप से स्मृति का अनुकूलन कर सकते हैं, सूचकांक प्रकार के लिए पूर्णांक चौड़ाई का अनुकूलन आदि

बात से दूसरे शब्दों में बयान:

struct RobinHashTable(K, V, size_t maxLength) { 
    static if (maxLength < ushort.max-1) { 
    alias CellIdx = ushort; 
    } else { 
    alias CellIdx = uint; 
    } 

    static if (K.sizeof % 8 < 7) { 
    align(8) struct KV { 
     align(1): 
     K k; 
     ubyte cellData; 
     align(8): 
     V v; 
    } 
    } else { 
    align(8) struct KV { 
     align(8): 
     K k; 
     V v; 
     align(1): 
     ubyte cellData; 
    } 
    } 
} 
संबंधित मुद्दे