Fix ambiguous MString << JString::Proxy overload resolution

JString::Proxy offers several implicit conversion operators (ZString,
MString, std::string, double, bool) so a single $[...]-style access can
be used wherever any of those types is expected. That flexibility made
"MString << Proxy" genuinely ambiguous: operator ZString() and
operator MString() (via its own implicit upcast to ZString) both satisfy
MString::operator<<(ZString), and operator double()/operator bool() both
satisfy MString::operator<<(int) via a standard numeric conversion, so
the compiler had no basis to prefer one conversion path over another.

Fixed the same way Proxy already solves this exact problem for
std::cout << proxy - a dedicated friend operator<<(MString&, const
Proxy&) that needs no conversion at all, so it's always the preferred
candidate. Verified by actually running testing/jstring_test.cpp (not
just compiling it) - the line that used to fail to compile now correctly
prints "this is a test: this is a comment".

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Brad ArantandClaude Sonnet 5 committed 2026-08-23 15:11:56 -07:00
1 parent bf6810b781
commit 5b6d4ea8ab
2 files changed
+24

No files matched your search

+7
View File
@@ -12,6 +12,13 @@ namespace coreutils {
return os;
}
MString &operator<<(MString &ms, const JString::Proxy &proxy) {
ZString tempkey = proxy.key;
ZString temp = proxy.jstring.find(tempkey);
ms << temp;
return ms;
}
JString::JString() : MString("{}") {}
// ---------------------------------------------------------------------
+17
View File
@@ -105,6 +105,23 @@ namespace coreutils {
friend std::ostream &operator<<(std::ostream &os, const Proxy &proxy);
///
/// Proxy offers several implicit conversion operators below (to
/// ZString, MString, std::string, double, bool) so a single $[...]-
/// style access can be used wherever any of those types is expected.
/// That flexibility makes "MString << Proxy" genuinely ambiguous on
/// its own - operator ZString() and operator MString() (via its own
/// implicit upcast to ZString) both satisfy MString::operator<<(ZString),
/// and operator double()/operator bool() both satisfy
/// MString::operator<<(int) via a standard numeric conversion - so
/// the compiler has no way to prefer one path over another. This
/// exact-match overload (mirroring the ostream one above, which
/// solves the same problem for std::cout << proxy) resolves it by
/// giving MString a candidate that needs no conversion at all.
///
friend MString &operator<<(MString &ms, const Proxy &proxy);
operator coreutils::ZString () {
return jstring.find(key);
}