std::regex_search implementation error?

Asked 1 years ago, Updated 1 years ago, 100 views

Some of the std::regex implementations in C++11 seem to not work well.

std::regex_search overloads that are used in the following code are not compiled:

#include<iostream>
# include <regex>



int main(void){
    std::string str = std::string("foobar");
    std::regex re(R"(foo)");
    std::smatch match;

    std::regex_search(str.begin(), str.end(), match, re);

    if(match.size()>0)
        std::cout<<match[0].str();

    return 0;
}

Compiling this code will cause an error stating that there is no overload matching the argument given in std::regex_search.
So when I looked into the cause, I found out that it was apparently throwing out this error when I gave it an iterator of string and also when I gave it std::smatch as match_results.

Now let's look at the definition of the desired overload in regex_search.

template<class_BidIt,
    class_Alloc,
    class_Elem,
    class_RxTraits>inline
    bool regex_match(_BidIt_First,_BidIt_Last,
        match_results<_BidIt,_Alloc>&_Matches,
        const basic_regex<_Elem, _RxTrates>&_Re,
        regex_constants::match_flag_type_Flgs=
            regex_constants::match_default);

It is shown thatNow, if you look at the function call I just made, each type of template is
_BidIt=std:string::iterator
_Elem=char (because the definition of regex is "typedef basic_regex<char>regex;")
It is shown as .(_Alloc,_RxTraits are omitted as they are irrelevant this time (you can ignore them as they are defaulted)

Therefore, if you rewrite the definition of the function:

bool regex_match(std:string::iterator_First,
    std::string::iterator_Last,
    match_results<std::string::iterator>&_Matches,
    const basic_regex<char>&_Re);

Now, since this does not match the type of argument, it means that the type of _Matches does not match.(because only _Matches are not involved in template type decisions)
Now, if you look at the definition of std::smatch, you can see

typedef match_results<string::const_iterator>smatch;

The template type given to match_results is different from iiterator と and conconst_iterator との, and it certainly does not match.(Finally, the cause is known)
Well, it's true that the compilation doesn't go through.

So, if you rewrite the code to something like the one below, it certainly works.

#include<iostream>
# include <regex>

namespace myStd {
    typeef std::match_results<std::string::iterator>smatch;
}

int main(void){
    std::string str = std::string("foobar");
    std::regex re(R"(foo)");
    myStd::smatch match;

    std::regex_search(str.begin(), str.end(), match, re);

    if(match.size()>0)
        std::cout<<match[0].str();

    return 0;
}

(Conversely, when you give the iterator to the function std::regex_search, you can cast it to (std::string::const_iterator) and it works well.)

However, it feels strange to rewrite the definition of std on your own.
There was no specific mention of this problem when I looked it up on the Internet, and I didn't know the cause.

Therefore, I would appreciate it if you could tell me what the best solution to this problem is and what is the root cause of this problem after all.

c++ c++11

2022-09-30 15:03

1 Answers

std::regex_search of the seven overloads provided

template<class BidirIt, 
          class Alloc, class CharT, class Trains >
bool regex_search(BidirIt first, BidirIt last,
                   std::match_results<BidirIt, Alloc>&m,
                   constd::basic_regex<CharT, Trats>&e,
                   std::regex_constants::match_flag_type flags= 
                       std::regex_constants::match_default);

is expected, but the first and second arguments are str.begin(), and the BidirIt template provisional arguments are std:string::iterator.Then the third argument is match and is of type std::smatch&.

where std::match_results

typedef std::match_results<std::string::const_iterator>std::smatch;

The BidirIt template provisional argument must be of type std:string::const_iterator.

The compilation error is caused by a mismatch between string:iteratorstring::const_iterator, so you can resolve it by using cbegin(str)cend(str) or vice versa

std::match_results<std::string::iterator> match;

You can also define it as .

The fundamental purpose of using the iterator is to allow the program to control the start and end positions of the search, so using the iterator as a const value is not very meaningful

C++ concepts may refer to InputIterator in Iterator, but std:string::iterator is also OutputIterator.In other words, the recipient of the iterator (regex_search()) is allowed to change the value.

In some cases, the caller explicitly selects string::const_iterator to indicate that the change is not accepted.

If you are pointing out a problem with implementation, you should present a specific implementation that has been verified to work.


2022-09-30 15:03

If you have any answers or tips


© 2024 OneMinuteCode. All rights reserved.