Don't clobber std::string_view equality with char *
Make the wxString(std::string_view) constructor explicit.
Otherwise, when comparing a std::string_view with a const char *, the
cast to wxString will be considered as a candidate for the comparison,
ultimately causing an "ambiguous overload for 'operator=='" error.
For example, this sample only builds if the constructor is explicit:
#include <wx/string.h>
#include <string_view>
int main() {
std::string_view view = "abc";
const char *str = "abc";
return view == str;
}
However, making the constructor explicit will break assignment:
std::string_view view = "abc";
wxString s;
s = view; // Error: no match for "operator="
That we can fix by implementing operator=(std::string_view)
That, however, introduces another ambiguity:
std::string str = "abc";
wxString s;
s = str; // Ambiguous between s = wxString(str)
and s = std::string_view(str)
That we can fix by implementing operator=(std::string)
Finally, note that some rather obscure ambiguities remain, such as:
wxString s;
s = {"abc", 2}; // Ambiguous between s = wxString("abc", 2)
and s = std::string_view("abc", 2)
Avoiding them is not simple (https://cplusplus.github.io/LWG/issue2946)
and doesn't add much value.
Closes #23834.
This commit is contained in:
parent
b3cfab1433
commit
19936c2176
3 changed files with 39 additions and 2 deletions
|
|
@ -108,6 +108,11 @@ Changes in behaviour which may result in build errors
|
||||||
compatible with the previous wxWidgets versions, but now compare values, and
|
compatible with the previous wxWidgets versions, but now compare values, and
|
||||||
not pointers, in their Index() member function.
|
not pointers, in their Index() member function.
|
||||||
|
|
||||||
|
- Due to the possibility to construct wxString from std::string_view some
|
||||||
|
previously valid code, such as "wxstr = {"Hello", 2}", is now ambiguous.
|
||||||
|
Please use explicit class name, e.g. "wxstr = wxString{"Hello", 2}" to
|
||||||
|
preserve the previous behaviour.
|
||||||
|
|
||||||
- Generic wxSearchCtrl doesn't provide methods that make sense only for
|
- Generic wxSearchCtrl doesn't provide methods that make sense only for
|
||||||
multiline text controls any longer, for consistency with the other ports.
|
multiline text controls any longer, for consistency with the other ports.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1263,7 +1263,7 @@ public:
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef wxHAS_STD_STRING_VIEW
|
#ifdef wxHAS_STD_STRING_VIEW
|
||||||
wxString(std::wstring_view view)
|
explicit wxString(std::wstring_view view)
|
||||||
{ assign(view.data(), view.length()); }
|
{ assign(view.data(), view.length()); }
|
||||||
#endif // wxHAS_STD_STRING_VIEW
|
#endif // wxHAS_STD_STRING_VIEW
|
||||||
|
|
||||||
|
|
@ -1272,7 +1272,7 @@ public:
|
||||||
{ assign(str.c_str(), str.length()); }
|
{ assign(str.c_str(), str.length()); }
|
||||||
|
|
||||||
#ifdef wxHAS_STD_STRING_VIEW
|
#ifdef wxHAS_STD_STRING_VIEW
|
||||||
wxString(std::string_view view)
|
explicit wxString(std::string_view view)
|
||||||
{ assign(view.data(), view.length()); }
|
{ assign(view.data(), view.length()); }
|
||||||
#endif // wxHAS_STD_STRING_VIEW
|
#endif // wxHAS_STD_STRING_VIEW
|
||||||
#endif // wxNO_IMPLICIT_WXSTRING_ENCODING
|
#endif // wxNO_IMPLICIT_WXSTRING_ENCODING
|
||||||
|
|
@ -1883,6 +1883,29 @@ public:
|
||||||
{ return assign(s); }
|
{ return assign(s); }
|
||||||
#endif // wxNO_IMPLICIT_WXSTRING_ENCODING
|
#endif // wxNO_IMPLICIT_WXSTRING_ENCODING
|
||||||
|
|
||||||
|
#if wxUSE_UNICODE_WCHAR
|
||||||
|
wxString& operator=(const std::wstring& str) { m_impl = str; return *this; }
|
||||||
|
wxString& operator=(std::wstring&& str) noexcept { m_impl = std::move(str); return *this; }
|
||||||
|
#else // wxUSE_UNICODE_UTF8
|
||||||
|
wxString& operator=(const std::wstring& str)
|
||||||
|
{ return assign(str.c_str(), str.length()); }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef wxHAS_STD_STRING_VIEW
|
||||||
|
wxString& operator=(std::wstring_view view)
|
||||||
|
{ return assign(view.data(), view.length()); }
|
||||||
|
#endif // wxHAS_STD_STRING_VIEW
|
||||||
|
|
||||||
|
#ifndef wxNO_IMPLICIT_WXSTRING_ENCODING
|
||||||
|
wxString& operator=(const std::string& str)
|
||||||
|
{ return assign(str.c_str(), str.length()); }
|
||||||
|
|
||||||
|
#ifdef wxHAS_STD_STRING_VIEW
|
||||||
|
wxString& operator=(std::string_view view)
|
||||||
|
{ return assign(view.data(), view.length()); }
|
||||||
|
#endif // wxHAS_STD_STRING_VIEW
|
||||||
|
#endif // wxNO_IMPLICIT_WXSTRING_ENCODING
|
||||||
|
|
||||||
// string concatenation
|
// string concatenation
|
||||||
// in place concatenation
|
// in place concatenation
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -690,5 +690,14 @@ TEST_CASE("StdString::View", "[stdstring]")
|
||||||
std::string_view strViewInvalidUTF(strInvalidUTF);
|
std::string_view strViewInvalidUTF(strInvalidUTF);
|
||||||
|
|
||||||
CHECK( "" == wxString::FromUTF8(strViewInvalidUTF) );
|
CHECK( "" == wxString::FromUTF8(strViewInvalidUTF) );
|
||||||
|
|
||||||
|
/* Ensure we don't clobber comparisons on base types */
|
||||||
|
std::string_view view = "abc";
|
||||||
|
const char *str = "abc";
|
||||||
|
CHECK( view == str );
|
||||||
|
|
||||||
|
std::wstring_view wview = L"abc";
|
||||||
|
const wchar_t *wstr = L"abc";
|
||||||
|
CHECK( wview == wstr );
|
||||||
}
|
}
|
||||||
#endif // wxHAS_STD_STRING_VIEW
|
#endif // wxHAS_STD_STRING_VIEW
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue