2015-10-15 5 views
14

यहाँ MCVE है:सरल std :: regex_search() कोड एप्पल बजना साथ संकलन नहीं होगा ++ -std = C++ 14

#include <iostream> 
#include <regex> 

std::string s() 
{ 
    return "test"; 
} 

int main() 
{ 
    static const std::regex regex(R"(\w)"); 
    std::smatch smatch; 

    if (std::regex_search(s(), smatch, regex)) { 
     std::cout << smatch[0] << std::endl; 
    } 

    return 0; 
} 

यह साथ ठीक संकलित:

$ बजना ++ -std = C++ 11 main.cpp

नहीं बल्कि साथ:

$ बजना ++ -std = C++ 14 main.cpp

त्रुटि बाद में मामले में संदेश (-std साथ = C++ 14):

main.cpp:14:9: error: call to deleted function 'regex_search' 
    if (std::regex_search(s(), smatch, regex)) { 
     ^~~~~~~~~~~~~~~~~ 
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/regex:5998:1: note: 
     candidate function [with _ST = std::__1::char_traits<char>, _SA = std::__1::allocator<char>, 
     _Ap = std::__1::allocator<std::__1::sub_match<std::__1::__wrap_iter<const char *> > >, _Cp = 
     char, _Tp = std::__1::regex_traits<char>] has been explicitly deleted 
regex_search(const basic_string<_Cp, _ST, _SA>&& __s, 
^ 
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/regex:2876:5: note: 
     candidate function [with _ST = std::__1::char_traits<char>, _SA = std::__1::allocator<char>, 
     _Ap = std::__1::allocator<std::__1::sub_match<std::__1::__wrap_iter<const char *> > >, _Cp = 
     char, _Tp = std::__1::regex_traits<char>] 
    regex_search(const basic_string<_Cp, _ST, _SA>& __s, 
    ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/regex:2851:5: note: 
     candidate template ignored: deduced conflicting types for parameter '_Bp' 
     ('std::__1::basic_string<char>' vs. 'std::__1::match_results<std::__1::__wrap_iter<const char 
     *>, std::__1::allocator<std::__1::sub_match<std::__1::__wrap_iter<const char *> > > >') 
    regex_search(_Bp, _Bp, const basic_regex<_Cp, _Tp>&, 
    ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/regex:2857:5: note: 
     candidate template ignored: could not match 'const _Cp *' against 'std::string' (aka 
     'basic_string<char, char_traits<char>, allocator<char> >') 
    regex_search(const _Cp*, const _Cp*, 
    ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/regex:2863:5: note: 
     candidate template ignored: could not match 'const _Cp *' against 'std::string' (aka 
     'basic_string<char, char_traits<char>, allocator<char> >') 
    regex_search(const _Cp*, match_results<const _Cp*, _Ap>&, const basic_regex<_Cp, _Tp>&, 
    ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/regex:2869:5: note: 
     candidate template ignored: could not match 'basic_regex' against 'match_results' 
    regex_search(const basic_string<_Cp, _ST, _SA>& __s, 
    ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/regex:5963:1: note: 
     candidate template ignored: could not match 'const _CharT *' against 'std::string' (aka 
     'basic_string<char, char_traits<char>, allocator<char> >') 
regex_search(const _CharT* __str, const basic_regex<_CharT, _Traits>& __e, 
^ 
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/regex:2839:5: note: 
     candidate function template not viable: requires at least 4 arguments, but 3 were provided 
    regex_search(_Bp, _Bp, match_results<_Bp, _Ap>&, const basic_regex<_Cp, _Tp>&, 
    ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/regex:2845:5: note: 
     candidate function template not viable: requires at least 4 arguments, but 3 were provided 
    regex_search(const _Cp*, const _Cp*, match_results<const _Cp*, _Ap>&, 
    ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/regex:2884:5: note: 
     candidate function template not viable: requires at least 4 arguments, but 3 were provided 
    regex_search(__wrap_iter<_Iter> __first, 
    ^
1 error generated. 

संकलक संस्करण जानकारी:

$ clang++ -v 
Apple LLVM version 7.0.0 (clang-700.0.72) 
Target: x86_64-apple-darwin15.0.0 
Thread model: posix 

तो, क्या गलत है?

+2

यह ध्यान रखना दिलचस्प है कि gcc/libstdC++ में यह C++ 11 और C++ 14 दोनों में विफल रहा है जो एक अच्छी चीज की तरह लगता है क्योंकि यह मूल रूप से अपरिभाषित व्यवहार है। –

+1

आप जानते हैं कि मुझे लगभग यकीन था कि मैंने यह समस्या पहले देखने से पहले देखी थी: [विजुअल स्टूडियो regex_iterator बग?] (Http://stackoverflow.com/q/29895747/1708801) हालांकि यह regex_iterator/regex_token_iterator के साथ है। –

उत्तर

9

जहां std::regex_search अब एक आर-मूल्य

template< class STraits, class SAlloc, 
      class Alloc, class CharT, class Traits > 
bool regex_search(const std::basic_string<CharT,STraits,SAlloc>&&, 
        std::match_results< 
         typename std::basic_string<CharT,STraits,SAlloc>::const_iterator, 
         Alloc>&, 
        const std::basic_regex<CharT, Traits>&, 
        std::regex_constants::match_flag_type flags = 
         std::regex_constants::match_default) = delete; 

यह लेने के लिए अनुमति दी है अधिभार कि लेता है के रूप में जोड़ा गया है एक परिवर्तन से सी ++ 11 सी ++ 14 के लिए जा रहा था एक const std::string&

अस्थायी तार को स्वीकार करने से निषिद्ध है, अन्यथा इस समारोह स्ट्रिंग iterators कि तुरंत अमान्य हो साथ match_results मीटर भरता है।

तो तुम अब एक अस्थायी std::regex_search लिए सी ++ 14

की हम बस s() से लौटने के मुख्य में एक चर में संग्रहीत करने और उपयोग करने वाले std::regex_search कॉल करने के लिए अपनी कोड को ठीक करने के रूप में पारित कर सकते हैं।

#include <iostream> 
#include <regex> 

std::string s() 
{ 
    return "test"; 
} 

int main() 
{ 
    static const std::regex regex(R"(\w)"); 
    std::smatch smatch; 

    auto search = s(); 
    if (std::regex_search(search, smatch, regex)) { 
     std::cout << smatch[0] << std::endl; 
    } 

    return 0; 
} 

Live Example

+1

तो, मुझे मुख्य() में स्थानीय std :: स्टिंग वैरिएबल बनाने की आवश्यकता है, इसे एस() द्वारा वापस लौटाया गया है, और फिर इस चर को std :: regex_search में पास करें, है ना? – Wildcat

+1

@ विल्डकैट हां। उत्तर में जोड़ा गया – NathanOliver

6

इस बीच सी ++ 11 और सी ++ 14 बदल दिया है। अगर हम cppreference section for std::regex_search करने के लिए जाने हम देख सकते हैं कि अधिभार है कि एक rvalue संदर्भ लेता है के बाद से सी ++ 14 नष्ट कर दिया गया:

template< class STraits, class SAlloc, 
      class Alloc, class CharT, class Traits > bool regex_search(const std::basic_string<CharT,STraits,SAlloc>&&, 
        std::match_results< 
         typename std::basic_string<CharT,STraits,SAlloc>::const_iterator, 
         Alloc 
        >&, 
        const std::basic_regex<CharT, Traits>&, 
        std::regex_constants::match_flag_type flags = 
         std::regex_constants::match_default) = delete; 

यह LWG issue 2329: regex_match()/regex_search() with match_results should forbid temporary strings जो कहते हैं की वजह से बदल गया था (जोर मेरा):

const regex r(R"(meow(\d+)\.txt)"); 
smatch m; 
if (regex_match(dir_iter->path().filename().string(), m, r)) { 
    DoSomethingWith(m[1]); 
} 

यह कभी कभी दुर्घटनाओं:

निम्नलिखित कोड पर विचार करें। समस्या यह है कि dir_iter-> पथ()। फ़ाइल नाम()। स्ट्रिंग() एक अस्थायी स्ट्रिंग देता है, तो match_results में अमान्य अस्थायी स्ट्रिंग में अमान्य इटरेटर्स शामिल हैं।

अस्थायी तारों को स्वीकार करने के लिए regex_match/regex_search (str, reg) के लिए यह ठीक है, क्योंकि वे बस बूल लौटते हैं। हालांकि, match_results लेने वाले ओवरलोड को अस्थायी स्ट्रिंग को रोकना चाहिए।

और वास्तव में अगर हम एक गैर अस्थायी उपयोग करें:

std::string s1 = s() ; 

if (std::regex_search(s1, smatch, regex)) { 
//... 
} 

यह संकलित (see it live) और अब अपरिभाषित व्यवहार दिखाता है।

यह ध्यान रखना दिलचस्प है कि gcc/libstdC++ में यह अधिभार C++ 11 मोड में see it live में हटा दिया गया है। चूंकि यह अनिर्धारित व्यवहार है, यह एक अच्छा समाधान की तरह लगता है।

यह समस्या लाइब्रेरी के अन्य क्षेत्रों में भी दिखाई देती है Visual Studio regex_iterator Bug? जो एक ही समस्या से संबंधित है लेकिन regex_iterator/regex_token_iterator के साथ।

2

यह एक बग नहीं है, लेकिन अपेक्षित व्यवहार है। कारण यह है कि s() एक अस्थायी स्ट्रिंग देता है, regex_searchregex_match का उपयोग करता है और इसके परिणामस्वरूप यदि एक अस्थायी स्ट्रिंग का उपयोग किया गया था तो मिलान परिणामों में एक स्ट्रिंग में इटरेटर शामिल होंगे जो अब मौजूद नहीं है। यह अपरिभाषित व्यवहार होता। इस प्रकार, समिति ने सी ++ 14 में इस regex_search अधिभार को समाप्त कर दिया।

तुम भी मानक 28.4 हैडर सार [re.syn] में इस बात की पुष्टि कर सकते हैं:

template <class ST, class SA, class Allocator, class charT, class traits> 
bool regex_search(const basic_string<charT, ST, SA>&&, 
match_results< 
typename basic_string<charT, ST, SA>::const_iterator, 
Allocator>&, 
const basic_regex<charT, traits>&, 
regex_constants::match_flag_type = 
regex_constants::match_default) = delete; 

आप अधिभार कि एक basic_string करने के लिए एक rvalue लेता है नष्ट कर दिया चिह्नित है देख सकते हैं।

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