From 718023606370d7c0f972acb0ba83df3383b8800a Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Mon, 27 Mar 2017 11:22:44 +0200 Subject: 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 Reviewed-by: Lars Knoll --- src/corelib/tools/qstringview.h | 27 ++++++++++----------------- 1 file changed, 10 insertions(+), 17 deletions(-) (limited to 'src/corelib/tools/qstringview.h') 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 using if_compatible_string = typename std::enable_if::value, bool>::type; + template + using if_compatible_qstring_like = typename std::enable_if::value || std::is_same::value, bool>::type; + template 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 = 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 = true> + QStringView(const String &str) Q_DECL_NOTHROW : QStringView(str.isNull() ? nullptr : str.data(), size_type(str.size())) {} +#endif template = true> QStringView(const StdBasicString &str) Q_DECL_NOTHROW -- cgit v1.2.3