2016-01-07 11 views
9

ध्यान दें, मैं दृश्य स्टूडियो का उपयोग कर रहा 2013std :: regex निर्माता फेंकता एक अपवाद

किसी रेगुलर एक्सप्रेशन का यह सरल निर्माण फेंकता std::regex_error :

bool caseInsensitive = true; 
char pattern[] = "\\bword\\b"; 
std::regex re(pattern, std::regex_constants::ECMAScript | (caseInsensitive ? std::regex_constants::icase : 0)); 

वास्तविक त्रुटि अपवाद वस्तु पर what द्वारा लौटाए गए संगत नहीं है। आम तौर पर यह एक बेमेल पेरेथेसिस या ब्रेस है। क्यूं कर?

उत्तर

11

समस्या std::regex के लिए उपलब्ध कई रचनाकारों के कारण उत्पन्न होती है। कन्स्ट्रक्टर में ट्रेसिंग ने इसे एक का उपयोग करके दिखाया कि मेरा इरादा नहीं था!

मैं इस एक का उपयोग करना चाहता था:

explicit basic_regex(_In_z_ const _Elem *_Ptr, 
    flag_type _Flags = regex_constants::ECMAScript) 

लेकिन मैं बजाय इस एक मिल:

basic_regex(_In_reads_(_Count) const _Elem *_Ptr, size_t _Count, 
    flag_type _Flags = regex_constants::ECMAScript) 

झंडे में त्रिगुट अभिव्यक्ति int को बदलने के लिए प्रकार का कारण बनता है, जिस पर अब मैचों कन्स्ट्रक्टर हस्ताक्षर में flag_type। चूंकि size_t पर मेल करता है, इसलिए यह उस निर्माता को इसके बजाय कॉल करता है। झंडे को स्ट्रिंग के आकार के रूप में गलत व्याख्या किया जाता है, जिसके परिणामस्वरूप अपरिभाषित व्यवहार होता है जब स्ट्रिंग के अंत से पहले की स्मृति को एक्सेस किया जाता है।

समस्या विजुअल स्टूडियो के लिए विशिष्ट नहीं है। मैं इसे जीसीसी में डुप्लिकेट करने में सक्षम था: http://ideone.com/5DjYiz

इसे दो तरीकों से तय किया जा सकता है। पहला तर्क का एक स्पष्ट डाली है:

std::regex re(pattern, static_cast<std::regex::flag_type>(std::regex_constants::ECMAScript | (caseInsensitive ? std::regex_constants::icase : 0))); 

दूसरा त्रिगुट अभिव्यक्ति में पूर्णांक स्थिरांक से बचने के लिए है:

std::regex re(pattern, caseInsensitive ? std::regex_constants::ECMAScript | std::regex_constants::icase : std::regex_constants::ECMAScript); 
6

मैं प्रस्तावित समाधान विशेष रूप से सम्मोहक या सौंदर्य की दृष्टि से मनभावन दोनों में से किसी भी नहीं मिलता है। मुझे लगता है कि मैं कुछ इस तरह पसंद करते हैं:

auto options = std::regex_constants::ECMAScript; 
if (caseInsensitive) 
    options |= std::regex_constants::icase; 

std::regex re(pattern, options); 

, तो कुछ गुमराह कारण के लिए, तुम सच में कोड की एक पंक्ति पर जोर देते हैं, मैं त्रिगुट में सही प्रकार की एक मूल्य-निर्माण वस्तु का उपयोग करेंगे अभिव्यक्ति:

std::regex re(pattern, std::regex_constants::ECMAScript | (caseInsensitive ? std::regex_constants::icase : std::regex_constants::std::regex_option_type{})); 

या, के बाद से ECMAScript डिफ़ॉल्ट है, तो आप का उपयोग करें:

std::regex re(pattern, (caseInsensitive ? std::regex_constants::icase : std::regex_constants::ECMAScript)); 

कम से कम मेरी आंखों के लिए, इनमें से पहला हालांकि स्पष्ट रूप से बेहतर है।

+0

आपका समाधान निश्चित रूप से अधिक पठनीय है, धन्यवाद। –

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