diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2021-08-31 08:54:24 -0700 |
---|---|---|
committer | Thiago Macieira <thiago.macieira@intel.com> | 2021-10-12 08:46:31 -0700 |
commit | 878b2047b52c93e904eb46ef1044819a8b5614ab (patch) | |
tree | db93eee403498d49a4eb870e4a0c8d0d96016fe1 /src/corelib/tools | |
parent | 2675c288e84e8e2392498e00a02ba0489c2f7358 (diff) |
QList::iterator: use templates for advancing operators
Because of the addition of the operator T*(), the expression "it + N"
where N was not exactly qsizetype but any other integer type was a
compilation failure because of ambiguous overload resolution.
With GCC it's apparently a warning:
warning: ISO C++ says that these are ambiguous, even though the worst conversion for the first is better than the worst conversion for the second:
note: candidate 1: ‘QList<T>::iterator QList<T>::iterator::operator+(qsizetype) const [with T = char; qsizetype = long long int]’
note: candidate 2: ‘operator+(char*, ptrdiff_t {aka long int})’ (built-in)
With Clang, it's an error:
error: use of overloaded operator '+' is ambiguous (with operand types 'QList<int>::const_iterator' and 'ptrdiff_t' (aka 'long'))
note: candidate function
inline const_iterator operator+(qsizetype j) const { return const_iterator(i+j); }
note: built-in candidate operator+(const int *, long)
Pick-to: 6.2
Fixes: QTBUG-96128
Change-Id: Ie72b0dd0fbe84d2caae0fffd16a06f23dd56b060
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
Diffstat (limited to 'src/corelib/tools')
-rw-r--r-- | src/corelib/tools/qlist.h | 32 |
1 files changed, 22 insertions, 10 deletions
diff --git a/src/corelib/tools/qlist.h b/src/corelib/tools/qlist.h index 07e5970faf..4bb9f1a028 100644 --- a/src/corelib/tools/qlist.h +++ b/src/corelib/tools/qlist.h @@ -162,13 +162,19 @@ public: inline iterator operator++(int) { T *n = i; ++i; return n; } inline iterator &operator--() { i--; return *this; } inline iterator operator--(int) { T *n = i; i--; return n; } - inline iterator &operator+=(qsizetype j) { i+=j; return *this; } - inline iterator &operator-=(qsizetype j) { i-=j; return *this; } - inline iterator operator+(qsizetype j) const { return iterator(i+j); } - inline iterator operator-(qsizetype j) const { return iterator(i-j); } - friend inline iterator operator+(qsizetype j, iterator k) { return k + j; } inline qsizetype operator-(iterator j) const { return i - j.i; } inline operator T*() const { return i; } + + template <typename Int> std::enable_if_t<std::is_integral_v<Int>, iterator> + &operator+=(Int j) { i+=j; return *this; } + template <typename Int> std::enable_if_t<std::is_integral_v<Int>, iterator> + &operator-=(Int j) { i-=j; return *this; } + template <typename Int> std::enable_if_t<std::is_integral_v<Int>, iterator> + operator+(Int j) const { return iterator(i+j); } + template <typename Int> std::enable_if_t<std::is_integral_v<Int>, iterator> + operator-(Int j) const { return iterator(i-j); } + template <typename Int> friend std::enable_if_t<std::is_integral_v<Int>, iterator> + operator+(Int j, iterator k) { return k + j; } }; class const_iterator { @@ -206,13 +212,19 @@ public: inline const_iterator operator++(int) { const T *n = i; ++i; return n; } inline const_iterator &operator--() { i--; return *this; } inline const_iterator operator--(int) { const T *n = i; i--; return n; } - inline const_iterator &operator+=(qsizetype j) { i+=j; return *this; } - inline const_iterator &operator-=(qsizetype j) { i-=j; return *this; } - inline const_iterator operator+(qsizetype j) const { return const_iterator(i+j); } - inline const_iterator operator-(qsizetype j) const { return const_iterator(i-j); } - friend inline const_iterator operator+(qsizetype j, const_iterator k) { return k + j; } inline qsizetype operator-(const_iterator j) const { return i - j.i; } inline operator const T*() const { return i; } + + template <typename Int> std::enable_if_t<std::is_integral_v<Int>, const_iterator> + &operator+=(Int j) { i+=j; return *this; } + template <typename Int> std::enable_if_t<std::is_integral_v<Int>, const_iterator> + &operator-=(Int j) { i-=j; return *this; } + template <typename Int> std::enable_if_t<std::is_integral_v<Int>, const_iterator> + operator+(Int j) const { return const_iterator(i+j); } + template <typename Int> std::enable_if_t<std::is_integral_v<Int>, const_iterator> + operator-(Int j) const { return const_iterator(i-j); } + template <typename Int> friend std::enable_if_t<std::is_integral_v<Int>, const_iterator> + operator+(Int j, const_iterator k) { return k + j; } }; using Iterator = iterator; using ConstIterator = const_iterator; |