summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
authorMarc Mutz <marc.mutz@kdab.com>2017-03-27 11:22:44 +0200
committerMarc Mutz <marc.mutz@kdab.com>2017-03-29 12:29:35 +0000
commit718023606370d7c0f972acb0ba83df3383b8800a (patch)
tree80f7929207bc73a1c5732d382c55cca2f1986621 /src/corelib
parente9c06b25af47e869028c7a56a679fda7b4475f38 (diff)
QStringView: improve manual overload management
We want to prevent QStringView(QChar|QLatin1String|QByteArray|const char*) from compiling as QStringView(QString(...)), so I added = delete'ed ctors for these types to QStringView. However, that makes QStringView participate in overload resolution for these types. Even if the QStringView ctor will always fail to compile, the presence of these ctors alone makes calls to functions overloaded on QString and QStringView ambiguous: f(QStringView); f(QString); f(foo); // ambiguous f(QChar('f')) // ambiguous f(QLatin1String(foo)); // ambiguous f(QByteArray(foo)); // ambiguous Fix by making the QString and QStringRef constructors templates constrained to accept only these two types. This should also help to move the QStringView definition to before the QString one (as soon as we get rid of or start to ignore QString::Null), simplifying a lot of code in qstring.h down the line. This should also fix MSVC's accepting of two user-defined conversions which caused static non-compile-tests to fail in the initial QStringView patch, and which were therefore removed. This patch brings them back. Change-Id: I95ac38c0d31cd8c726f7e952017569d32e484413 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/tools/qstringview.h27
1 files changed, 10 insertions, 17 deletions
diff --git a/src/corelib/tools/qstringview.h b/src/corelib/tools/qstringview.h
index 5384e73039..b1722e4657 100644
--- a/src/corelib/tools/qstringview.h
+++ b/src/corelib/tools/qstringview.h
@@ -111,6 +111,9 @@ private:
template <typename T>
using if_compatible_string = typename std::enable_if<QtPrivate::IsCompatibleStdBasicString<T>::value, bool>::type;
+ template <typename T>
+ using if_compatible_qstring_like = typename std::enable_if<std::is_same<T, QString>::value || std::is_same<T, QStringRef>::value, bool>::type;
+
template <typename Char>
static Q_DECL_RELAXED_CONSTEXPR size_type lengthHelper(const Char *str) Q_DECL_NOTHROW
{
@@ -133,20 +136,6 @@ private:
static Q_DECL_CONSTEXPR const storage_type *castHelper(const storage_type *str) Q_DECL_NOTHROW
{ return str; }
- // prevent
- // T t; QStringView sv(t), T \in {QChar, QLatin1String, QByteArray, const char*}
- // from compiling as QStringView sv(QString(t)):
- QStringView(QChar) = delete;
- QStringView(QLatin1String) = delete;
- QStringView(const QByteArray &) = delete;
- QStringView(const char *) = delete;
-
-#ifdef Q_OS_WIN
- // prevent QStringView(Char), Char compatible, from compiling due to:
- // https://connect.microsoft.com/VisualStudio/feedback/details/2256407/c-two-user-defined-conversions-incorrectly-accepted-in-implicit-conversion-sequence
- template <typename Char, if_compatible_char<Char> = true>
- QStringView(Char) = delete;
-#endif
public:
Q_DECL_CONSTEXPR QStringView() Q_DECL_NOTHROW
: m_size(0), m_data(nullptr) {}
@@ -166,10 +155,14 @@ public:
Q_DECL_CONSTEXPR QStringView(const Char *str)
: QStringView(str, str ? lengthHelper(str) : 0) {}
- QStringView(const QString &str) Q_DECL_NOTHROW
- : QStringView(str.isNull() ? nullptr : str.data(), size_type(str.size())) {}
- QStringView(const QStringRef &str) Q_DECL_NOTHROW
+#ifdef Q_QDOC
+ QStringView(const QString &str) Q_DECL_NOTHROW;
+ QStringView(const QStringRef &str) Q_DECL_NOTHROW;
+#else
+ template <typename String, if_compatible_qstring_like<String> = true>
+ QStringView(const String &str) Q_DECL_NOTHROW
: QStringView(str.isNull() ? nullptr : str.data(), size_type(str.size())) {}
+#endif
template <typename StdBasicString, if_compatible_string<StdBasicString> = true>
QStringView(const StdBasicString &str) Q_DECL_NOTHROW