std::regex_match with another Allocator

倖福魔咒の 提交于 2019-12-24 17:17:39

问题


I'm stuck how to use the regex_match template with my own Memory STL Allocator.

This is my code:

FaF::smatch stringResults;
std::regex expression( "expression" );
std::regex_match( FaF::string-variable, stringResults, expression );

For std::match and std::string I was successful and therefore I use it in the above example:

namespace FaF
{
    using smatch = std::match_results<std::string::const_iterator,
                                          Allocator<std::string::const_iterator>>;
    using string = std::basic_string<char, std::char_traits<char>, Allocator<char>>;
}

My Allocator has some logging and I can see clearly, yes it is indeed used. When I understand the cppreference correctly, then std::regex does not have an allocator, but std::regex_match does.

My question:

How to define - according the above types - in the namespace FaF an additional template based on std::regex_match which is using my STL Memory Allocator?


回答1:


After studying the definition of std::regex_match in regex.h

  template<typename _Ch_traits, typename _Ch_alloc,
       typename _Alloc, typename _Ch_type, typename _Rx_traits>
    inline bool
    regex_match(const basic_string<_Ch_type, _Ch_traits, _Ch_alloc>& __s,
        match_results<typename basic_string<_Ch_type,
        _Ch_traits, _Ch_alloc>::const_iterator, _Alloc>& __m,
        const basic_regex<_Ch_type, _Rx_traits>& __re,
        regex_constants::match_flag_type __flags
        = regex_constants::match_default)
    { return regex_match(__s.begin(), __s.end(), __m, __re, __flags); }

I understood and realized that my own definition of FaF::string and defining my own FaF::smatch [definitions are in the question] is enough because the _Alloc is used there.

My code is like this:

void getBarDataEntryFromMySql( const FaF::string & memcacheBarDataEntry )
{
    const char expressionString [] = "expression";

    FaF::smatch stringResults;
    std::regex expression( expressionString );
    std::regex_match( memcacheBarDataEntry, stringResults, expression );

    ...
}

and it works. I was thinking too complicated...




回答2:


According to cppreference.com, the second argument of regex_match should be

std::match_results<typename std::basic_string<CharT,STraits,SAlloc>::const_iterator, Alloc>

where the first argument would be a std::basic_string<CharT,STraits,SAlloc>.

This would require your alias declarations in FaF to like somewhat like:

namespace FaF
{
    using string_type = std::basic_string<char, std::char_traits<char>,
                            Allocator<char>>;
    using match_type  = std::match_results<string_type::const_iterator, 
                            Allocator<string_type::const_iterator>>;
}

in order to have

  • results and
  • string characters allocated via your allocator and
  • correct arguments.



回答3:


FWIW, VS 2017 fails to compile the match_type, because it needs to use sub_match:

using match_type = std::match_results<string_type::const_iterator,
    Allocator<std::sub_match<string_type::const_iterator>>>;

EDIT: It doesn't actually seem possible to fully override the allocator used by std::regex in VS2017. There are some std::vector's that don't take the allocator param, used internally by the _Matcher object. This is annoying :(



来源:https://stackoverflow.com/questions/38124358/stdregex-match-with-another-allocator

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!