programforjoy
programforjoy

Reputation: 499

C++: Why I can't pass a pair of iterators to regex_search?

I try to pass a pair of iterators to represent a string sequence:

    #include<regex>
    #include<string>
    using namespace std;
    int main(int argc,char *argv[])
    {
        smatch results;
        string temp("abc");
        string test("abc");

        regex r(temp);
        auto iter = test.begin();
        auto end = test.end();

        if(regex_search(iter,end,results,r))
    cout<<results.str()<<endl;
        return 0;
    }

The error goes like:

error: no matching function for call to ‘regex_search(__gnu_cxx::__normal_iterator >&, __gnu_cxx::__normal_iterator >&, std::smatch&, std::regex&)’ if(regex_search(iter,end,results,r))

Upvotes: 4

Views: 331

Answers (2)

hlscalon
hlscalon

Reputation: 7552

regex_search expects a const_iterator but you are passing a std::string::iterator.


Make your string const

const string test("abc");

Declare a const_iterator

std::string::const_iterator iter = test.begin();
std::string::const_iterator end = test.end();

Or use cbegin and cend

auto iter = test.cbegin();
auto end = test.cend();

Upvotes: 0

NathanOliver
NathanOliver

Reputation: 180585

The issue you are having here is a type mismatch between the iterators you are passing to regex_search and the iterator defined for smatch. std::smatch is defined as:

typedef match_results<string::const_iterator> smatch;

and iter and end have the type of

string::iterator

When you call regex_search the iterator version is defined as

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

And as we can see the iterators and the iterators of the match_result have to match. If we change

auto iter = test.begin();
auto end = test.end();

To

auto iter = test.cbegin();
auto end = test.cend();

Then everything now has the type of string::const_iterator and it will compile

#include<regex>
#include<string>
#include <iostream>
using namespace std;
int main()
{
    smatch results;
    string temp("abc");
    string test("abc");

    regex r(temp);
    auto iter = test.cbegin();
    auto end = test.cend();

    if (regex_search(iter, end, results, r))
        cout << results.str() << endl;
    return 0;
}

Live Example

Upvotes: 3

Related Questions