2011-04-19 16 views
16

के लिए संकलन-समय पर जोर दें टेम्पलेट का उपयोग करना संभव है?स्ट्रिंग समानता

दो स्ट्रिंग स्थिरांक हैं। वे विभिन्न मॉड्यूल में परिभाषित से आते हैं। वे बराबर होना चाहिए, या यदि वे बराबर नहीं हैं तो मैं संकलन-समय त्रुटि बढ़ा दूंगा। क्या मैं टेम्पलेट का उपयोग कर ऐसा कर सकता हूं?

#define MY_STRING "foo" 
CompileAssertIfStringsNotEqual(MY_STRING, HIS_STRING); 

पीएस मुझे यह मानकर भ्रमित किया गया कि "एबीसी" [0] निरंतर अभिव्यक्ति है। यह नहीं। भाषा में अजीब चूक। यह "abc" [0] स्थिरता अभिव्यक्ति थी।

उत्तर

18

यह सी ++ 0x के साथ ही संभव है। सी ++ 03 के साथ कोई मौका नहीं।

संपादित करें: सी ++ 0x के लिए कॉन्स्टेक्सप्रस फ़ंक्शन। निम्नलिखित GCC4.6 के साथ काम करता है, हालांकि मानक इसे अनुमति देने में स्पष्ट नहीं है, और एक छोटा सा शब्द ट्विक था और इसे spec को अनुमति देने के लिए विचार किया जा रहा है।

constexpr bool isequal(char const *one, char const *two) { 
    return (*one && *two) ? (*one == *two && isequal(one + 1, two + 1)) 
    : (!*one && !*two); 
} 

static_assert(isequal("foo", "foo"), "this should never fail"); 
static_assert(!isequal("foo", "bar"), "this should never fail"); 

कंपाइलर को सभी रिकर्स में पहले से ही स्ट्रिंग अक्षर के पात्रों के संदर्भ को ट्रैक करने की आवश्यकता है। केवल पात्रों से अंतिम पढ़ने की अनुमति नहीं है (यदि आप स्क्विंट करते हैं, तो आप इसे अनुमति के रूप में पढ़ सकते हैं, आईएमओ)। अपने संकलक ऊपर सरल संस्करण को स्वीकार नहीं करना चाहता है, तो आप अपने मैक्रो घोषित सरणियों कर सकते हैं और फिर उन

#define CONCAT1(A, B) A ## B 
#define CONCAT(A, B) CONCAT1(A, B) 

#define CHECK_EQUAL(A, B) \ 
    constexpr char CONCAT(x1, __LINE__)[] = A, \ 
       CONCAT(x2, __LINE__)[] = B; \ 
    static_assert(isequal(CONCAT(x1, __LINE__), CONCAT(x2, __LINE__)), \ 
    "'" A "' and '" B "' are not equal!") 

यह निश्चित रूप से ठीक है की तुलना करें।

CHECK_EQUAL("foo", "foo"); /* will pass */ 
CHECK_EQUAL("foo", "bar"); /* will fail */ 

ध्यान दें कि CHECK_EQUAL कार्यों के अंदर उपयोग किया जा सकता है। एफसीडी ने अपने आमंत्रण प्रतिस्थापन में स्वचालित सरणी से पढ़ने के लिए constexpr कार्यों को अनुमति देने के लिए एक बदलाव किया है। DR1197 देखें।

+0

क्या आप सी ++ 0x रास्ता दिखा सकते हैं या एक लिंक प्रदान कर सकते हैं? – pmr

+0

+1 लेकिन, मुझे हमेशा संदेह है कि यह मेटाप्रोग्रामिंग का उपयोग कर सी ++ में संभव हो सकता है। लेकिन मैं इसे कभी पूरा करने में सक्षम नहीं हूं। क्षितिज पर सी ++ 0x के साथ, मैंने कोशिश छोड़ दी। –

+0

इसका मतलब है कि C++ टेम्पलेट भाषा में एक कंपाइलर लिखना संभव हो सकता है। वू हू! – Omnifarious

-3

नहीं। आप नहीं कर सकते। boost::mpl या boost प्रीप्रोसेसर लाइब्रेरी के साथ भी नहीं। यहां तक ​​कि यदि आप यह निर्धारित करना चाहते थे कि संकलक संकलन-समय पर एक ही सूचक मूल्य में सभी डुप्लिकेट स्ट्रिंग संदर्भों को जोड़ सकता है, तो पॉइंटर मान लिंक-टाइम तक मौजूद नहीं है। जो आप कार्यान्वित करना चाहते हैं वह प्रीप्रोसेसर समय पर होता है, और उसके बाद संकलन-समय पर जोर दिया जाता है।

+0

हम्म मुझे बताया गया था कि टेम्पलेट प्रीप्रोसेसर से अधिक शक्तिशाली हैं ....) – Andrei

+0

और फिर भी, टेम्पलेट्स विशेषज्ञता के लिए "उद्धृत तार" स्वीकार नहीं करते हैं। –

+0

न ही 'टेम्पलेट कुछ ' के विशेषज्ञता के लिए वे 'डबल' या 'फ्लोट' या किसी अन्य गैर-पूर्णांक मान को स्वीकार करते हैं। –

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