2009-03-29 15 views
5

एक्सएमएल सीरियलाइजेशन के लिए नाम-मूल्य जोड़ी बनाने के लिए BOOST_SERIALIZATION_NVP मैक्रो का उपयोग करते समय, कंपाइलर खुशी से निम्न कोड को संकलित करने की अनुमति देता है, भले ही तत्व का नाम वैध एक्सएमएल नहीं है तत्व और एक अपवाद फेंक दिया जाता है जब वास्तव में एक्सएमएल में वस्तु को क्रमानुसार करने की कोशिश कर रहा:बूस्ट सीरियलाइजेशन एनवीपी मैक्रो और गैर-एक्सएमएल-एलिमेंट कैरेक्टर

BOOST_SERIALIZATION_NVP(_member[index]) 

एक स्पष्ट ठीक उपयोग करने के लिए है:

boost::serialization::make_nvp("ValidMemberName", _member[index]) 

लेकिन किसी को भी बढ़ावा संशोधित करने के लिए एक तरह से सुझाव है कि कर सकते हैं ताकि अवैध तत्व नाम एक compilatio ट्रिगर करेगा एन त्रुटि? (इस प्रकार ऊपर सूक्ष्म बग को पकड़ने के लिए इकाई परीक्षण पर भरोसा नहीं)


संपादित करें:

एक विचार किसी भी तरह तत्व मैक्रो के लिए पारित के नाम के साथ एक डमी स्थानीय चर घोषित करने के लिए है, मानते हैं कि सी ++ में वैध पहचानकर्ताओं का सेट मान्य XML तत्वों का एक सबसेट है। पूरा यकीन नहीं है कि यह किया जा सकता है हालांकि।

+0

यह रनटाइम त्रुटि उत्पन्न करेगा 'क्या(): अमान्य एक्सएमएल टैग नाम' – alfC

उत्तर

1

मुझे लगता है कि आपका विचार शायद काम करेगा। मान्य सी ++ पहचानकर्ता ए-जेड, ए-जेड, 0-9 और अंडरस्कोर से बने होते हैं, जो वास्तव में एक्सएमएल आइडेंटिफायर का एक उचित सबसेट है (जो कि हाइफ़न, अवधि और सेट में यूनिकोड वर्णों का एक गुच्छा जोड़ता है)। ,

#define SAFE_BOOST_SERIALIZATION_NVP(name) \ 
    { int name = 0; } ; BOOST_SERIALZATION_NVP(name) 

ब्रेसिज़ डमी चर करने के लिए सिर्फ इतना है कि लाइन के विस्तार को सीमित ताकि आप फर्जी चर के साथ अपने कार्य को अव्यवस्थित नहीं करते:

आप एक संकलन समय त्रुटि प्राप्त करने के लिए इस तरह एक निर्माण की कोशिश कर सकते । शायद संकलक डमी वैरिएबल को भी अनुकूलित करता है, इसलिए कोई रनटाइम लागत नहीं है। जब मैं निम्नलिखित कोड में इस मैक्रो का उपयोग, मैं error: invalid intializer मिलती है:

#include "boost/serialization/nvp.hpp" 
#define SAFE_BOOST_SERIALIZATION_NVP(name) \ 
    { int name = 0; } ; BOOST_SERIALIZATION_NVP(name) 

int main(int argc, char *argv[]) 
{ 
    int foo[3] = { 10, 20, 30 }; 
    int bar = 10; 
    SAFE_BOOST_SERIALIZATION_NVP(foo[0]); 
    return 0; 
} 

अगर मैं SAFE_BOOST_SERIALIZATION_NVP करने के लिए कॉल में bar साथ foo[0] की जगह, यह कोई त्रुटि के साथ संकलित करता है।

+1

लेकिन मुझे नहीं लगता कि यह serialize फ़ंक्शन में उपयोग किए जाने पर काम करेगा। धारावाहिक (..) {संग्रह और SAFE_BOOST_SER_NVP (एम); } ... –

+0

@AssafLavie, आप सही हैं, हालांकि यह मामूली संशोधन (अंत में अतिरिक्त कोड) नौकरी करने लगता है: '# परिभाषित करें SAFE_BOOST_SERIALIZATION_NVP (नाम) \ BOOST_SERIALIZATION_NVP (नाम); {int name = 0;} ' – alfC

2

नाम के लिए एक्सएमएल वाक्य रचना का हवाला देते हुए:

NameStartChar ::= ":" | [A-Z] | "_" | [a-z] | [#xC0-#xD6] | [#xD8-#xF6] | [#xF8-#x2FF] | [#x370-#x37D] | [#x37F-#x1FFF] | [#x200C-#x200D] | [#x2070-#x218F] | [#x2C00-#x2FEF] | [#x3001-#xD7FF] | [#xF900-#xFDCF] | [#xFDF0-#xFFFD] | [#x10000-#xEFFFF] 
NameChar  ::= NameStartChar | "-" | "." | [0-9] | #xB7 | [#x0300-#x036F] | [#x203F-#x2040] 

मैं सी ++ नाम के साथ निम्नलिखित अंतर देख: प्रमुख _ C++ में आरक्षित किया जा सकता है, क्या इस प्रकार पर निर्भर करता है; कोलन, बिंदु और शून्य संकेत एक्सएमएल नामों में मान्य हैं। यूनिकोड वर्ण सी ++ में कुछ दुःख भी पैदा कर सकते हैं, लेकिन यह ज्यादातर कार्यान्वयन-निर्भर है।

[# x0300- # x036F] भाग उच्चारण (diacriticals) संयोजन कर रहे हैं, जो एक अतिरिक्त चिंता wrt नाम समानता हो सकता है।

तो, कोई समाधान नहीं है जो गैर वर्णमाला वर्णों को पकड़ता है। < :::>> एक स्माइली की तरह लग सकता है, लेकिन यह अच्छी तरह से गठित एक्सएमएल है। बाकी के लिए, आपका विचार काफी ठीक है। एरिक Melski का विचार एक अच्छा प्रयास है, लेकिन यह बहुत सारे वर्णमाला पात्रों को स्वीकार करता है। उदाहरण के लिए, foo[1], &foo, *foo, foo=0 या foo,bar। एक बेहतर विकल्प है: {using namespace name;}। यह foo::bar स्वीकार करेगा, लेकिन यह वास्तव में ठीक है - एक्सएम में foo :: बार की अनुमति है।

+0

लेकिन यदि 'name' पहले से ही नामस्थान नहीं है तो यह एक त्रुटि देगा। – alfC

1

यह दो उत्तरों के बीच एक संकर है, @Eric Melski (ज्यादातर सही --extra कोड define के अंत में होना चाहिए - लेकिन अपूर्ण समाधान - कुछ वर्जित नाम "फ़िल्टर नहीं" - और @MSalters ' ज्यादातर सही (- using namespace मनमाने ढंग से अविकसित नामों के लिए उपयोग नहीं किया जा सकता है--)।

मैं struct का उपयोग कर का प्रस्ताव:

#define SAFE_BOOST_SERIALIZATION_NVP(name) \ 
    BOOST_SERIALIZATION_NVP(name); {struct name{};} 

या अधिक जोखिम भरा:

#undef BOOST_SERIALIZATION_NVP 
#define BOOST_SERIALIZATION_NVP(name)        \ 
    boost::serialization::make_nvp(BOOST_PP_STRINGIZE(name), name); {struct name{};} 

जरूरत नहीं कहने के लिए है कि वहाँ इस के लिए कोई क्रम लागत।

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