问题
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