mirror of
https://github.com/fmtlib/fmt.git
synced 2026-09-13 14:22:26 +08:00
Don't let ADL pick to_string_view (#4938)
* Don't let ADL pick to_string_view
02bf4d1c disabled ADL for to_string_view by qualifying the is_string trait,
and has_to_string_view and char_t are qualified for the same reason. Two call
sites were left behind: value's string constructor and the write() overload
for types with a string view conversion. Both sit inside fmt::detail, where an
unqualified call adds the argument's own namespace to the overload set.
That splits the two halves of one decision. Both call sites are reached only
through has_to_string_view or char_t, which are defined by the qualified
expression, so ADL can never be needed to satisfy them - it can only add
candidates the gate never considered. When the argument's namespace declares a
to_string_view template, the two tie during partial ordering and the call is
ambiguous:
core.h(2211): error C2668: 'to_string_view': ambiguous call to overloaded
function
note: could be 'string_view N::to_string_view<T>(const T&)' [found using
argument-dependent lookup]
note: or 'basic_string_view<char> fmt::detail::to_string_view<T,0>(const T&)'
Both are reachable. format("{}", x) stores the argument through value's
constructor; to_string(x) passes it to detail::write unmapped, which lands on
the write() overload, as do FMT_COMPILE named fields and
nested_formatter::write_arg. Reverting either line alone breaks the build of
the test that covers it.
This turned up in Microsoft Office, which declares a constrained
to_string_view template next to its own string types. It only breaks where
those types are distinct classes, so the same code compiles on platforms whose
string types are std aliases - the ADL set is namespace std there and picks up
nothing.
One behaviour change worth noting: a non-template to_string_view in the
argument's namespace used to win outright at these call sites, so a type that
satisfies is_std_string_like via find_first_of and data() but has no size()
formatted through ADL and now fails to compile, because the trait only checks
that the qualified overload is viable, not that its body instantiates. That is
the removed extension point going away rather than a new restriction; ADL
to_string_view stopped being supported in 02bf4d1c.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
parent
e5d13d826f
commit
e91e92761a
@ -2208,7 +2208,7 @@ template <typename Context> class value {
|
||||
FMT_CONSTEXPR value(const T& x FMT_BUILTIN) {
|
||||
static_assert(std::is_same<C, char_type>::value,
|
||||
"mixing character types is disallowed");
|
||||
auto sv = to_string_view(x);
|
||||
auto sv = detail::to_string_view(x);
|
||||
string.data = sv.data();
|
||||
string.size = sv.size();
|
||||
}
|
||||
|
||||
@ -3815,7 +3815,7 @@ FMT_CONSTEXPR auto write(OutputIt out, basic_string_view<Char> value)
|
||||
template <typename Char, typename OutputIt, typename T,
|
||||
FMT_ENABLE_IF(has_to_string_view<T>::value)>
|
||||
constexpr auto write(OutputIt out, const T& value) -> OutputIt {
|
||||
return write<Char>(out, to_string_view(value));
|
||||
return write<Char>(out, detail::to_string_view(value));
|
||||
}
|
||||
|
||||
// FMT_ENABLE_IF() condition separated to workaround an MSVC bug.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user