This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of NAD status.
regex_replace() overloadsSection: 28.6.10.4 [re.alg.replace] Status: NAD Submitter: Stephan T. Lavavej Opened: 2007-09-22 Last modified: 2016-01-28
Priority: Not Prioritized
View all other issues in [re.alg.replace].
View all issues with NAD status.
Discussion:
Two overloads of regex_replace() are currently provided:
template <class OutputIterator, class BidirectionalIterator,
class traits, class charT>
OutputIterator
regex_replace(OutputIterator out,
BidirectionalIterator first, BidirectionalIterator last,
const basic_regex<charT, traits>& e,
const basic_string<charT>& fmt,
regex_constants::match_flag_type flags =
regex_constants::match_default);
template <class traits, class charT>
basic_string<charT>
regex_replace(const basic_string<charT>& s,
const basic_regex<charT, traits>& e,
const basic_string<charT>& fmt,
regex_constants::match_flag_type flags =
regex_constants::match_default);
const charT * are provided for regex_match() and
regex_search(), but not regex_replace(). This is inconsistent.The absence of const charT * overloads prevents ordinary-looking code from compiling, such as:
const string s("kitten");
const regex r("en");
cout << regex_replace(s, r, "y") << endl;
The compiler error message will be something like "could not deduce template argument for 'const std::basic_string<_Elem> &' from 'const char[1]'".
Users expect that anything taking a basic_string<charT> can also take a
const charT *. In their own code, when they write a function taking
std::string (or std::wstring), they can pass a const char * (or const
wchar_t *), thanks to basic_string's implicit constructor. Because the
regex algorithms are templated on charT, they can't rely on
basic_string's implicit constructor (as the compiler error message
indicates, template argument deduction fails first).
If a user figures out what the compiler error message means, workarounds
are available - but they are all verbose. Explicit template arguments
could be given to regex_replace(), allowing basic_string's implicit
constructor to be invoked - but charT is the last template argument, not
the first, so this would be extremely verbose. Therefore, constructing
a basic_string from each C string is the simplest workaround.
basic_strings can
impose performance costs that could be avoided by a library
implementation taking C strings and dealing with them directly.
(Currently, for replacement sources, C strings can be converted into
iterator pairs at the cost of verbosity, but for format strings, there
is no way to avoid constructing a basic_string.)
[ Sophia Antipolis: ]
We note that Boost already has these overloads. However, the proposed wording is provided only for 28.6.10.4 [re.alg.replace]; wording is needed for the synopsis as well. We also note that this has impact on
match_results::format, which may require further overloads.
[ 2009-07 Frankfurt: ]
Daniel to tweak for us.
[ 2009-07-25 Daniel tweaks both this issue and 727(i). ]
[ 2009-10 Santa Cruz: ]
Leave Open. Though we believe this is solved by the proposed resolution to 727(i).
[ 2010-01-27 Moved to Tentatively NAD after 5 positive votes on c++std-lib. Rationale added below. ]
Rationale:
Proposed resolution:
Provide additional overloads for regex_replace(): one additional
overload of the iterator-based form (taking const charT* fmt), and three
additional overloads of the convenience form (one taking const charT*
str, another taking const charT* fmt, and the third taking both const
charT* str and const charT* fmt). 28.6.10.4 [re.alg.replace]:
template <class OutputIterator, class BidirectionalIterator, class traits, class charT> OutputIterator regex_replace(OutputIterator out, BidirectionalIterator first, BidirectionalIterator last, const basic_regex<charT, traits>& e, const basic_string<charT>& fmt, regex_constants::match_flag_type flags = regex_constants::match_default);...
template <class traits, class charT> basic_string<charT> regex_replace(const basic_string<charT>& s, const basic_regex<charT, traits>& e, const basic_string<charT>& fmt, regex_constants::match_flag_type flags = regex_constants::match_default);