C++11に実装されているstd::regexについて、一部うまく動かない機能があるようです。

std::regex_searchのオーバーロードのうち、以下のコードで使われているものがコンパイルが通りません。

#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;
}

このコードをコンパイルすると、「std::regex_searchに与えられた引数と一致するオーバーロードが存在しない」という旨のエラーを吐きます。
そこで原因を調べてみると、どうやら「stringのイテレーターを与え」、なおかつ「match_resultsとしてstd::smatchを与える」ときにこのエラーを吐くようだということがわかってきました。

ここで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, _RxTraits>& _Re,
        regex_constants::match_flag_type _Flgs =
            regex_constants::match_default);

となっています。ここで先ほどの関数呼び出しと照らし合わせてみますと、テンプレートのそれぞれの型は、
_BidIt = std::string::iterator
_Elem = char (std::regexの定義が「typedef basic_regex<char> regex;」になっていることより)
になっています。(_Alloc,_RxTraitsは今回は関係ないので省略(デフォルト指定がなされているので無視できる))

よって、関数の定義を書き直すと以下のようになります。

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

さて、これに引数の型がマッチしないということですから、_Matchesの型がマッチしていないということになります。(_Matchesのみテンプレート型の決定に関与していないため)
ここでstd::smatchの定義を確認すると、

typedef match_results<string::const_iterator> smatch;

となっており、match_resultsに与えられているテンプレート型が「iterator」と「const_iterator」との異なる型になっており、確かに一致していません。(やっと原因判明)
まあ、確かにこれではコンパイルが通らないのもうなずけます。

そこで、以下のようなコードに書き換えると、確かにうまく動きます。

#include <iostream>
#include <regex>

namespace myStd {
    typedef 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;
}

(逆に、関数std::regex_searchにイテレーターを与える際に(std::string::const_iterator)にキャストしてやってもうまく動きます)

しかし、このようにstdの定義を自分で勝手に書き換えて使うというのは何だか変な感じです。
インターネット上で調べてもこの問題に関する言及が特にありませんし、原因もよくわかりませんでした。

そこで、この問題に対する最適解はどのようになるのか、結局この問題の根本的な原因はいったい何なのか、を教えていただけるとありがたいです。