-
Bug
-
Resolution: Done
-
P2: Important
-
None
-
5.12.2
-
None
-
gcc 8.2.1, arch
-
-
014d7ac65417ed9b5ffb85cca24d16564ff5005a (qt/qtbase/5.13)
Take this example code and compile it:
#include <QSharedPointer>
#include <memory>
struct Base1 {};
struct Base2 {};
struct Child1 : Base1 {};
struct Child2 : Base2 {};
template<template<typename> typename SmartPtr>
struct Overloaded
{
static void overloaded(const SmartPtr<const Base1> &) {}
static void overloaded(const SmartPtr<const Base2> &) {}
};
template<template<typename> typename SmartPtr>
void test()
{
Overloaded<SmartPtr>::overloaded(SmartPtr<Base1>{});
Overloaded<SmartPtr>::overloaded(SmartPtr<Base2>{});
Overloaded<SmartPtr>::overloaded(SmartPtr<const Base1>{});
Overloaded<SmartPtr>::overloaded(SmartPtr<const Base2>{});
Overloaded<SmartPtr>::overloaded(SmartPtr<Child1>{});
Overloaded<SmartPtr>::overloaded(SmartPtr<Child2>{});
Overloaded<SmartPtr>::overloaded(SmartPtr<const Child1>{});
Overloaded<SmartPtr>::overloaded(SmartPtr<const Child2>{});
}
int main()
{
test<std::shared_ptr>();
test<QSharedPointer>();
return 0;
}
You will be greeted with compile errors due to unexpected overload ambiguity:
test.cpp: In instantiation of ‘void test() [with SmartPtr = QSharedPointer]’:
test.cpp:33:26: required from here
test.cpp:20:37: error: call of overloaded ‘overloaded(QSharedPointer<Base1>)’ is ambiguous
Overloaded<SmartPtr>::overloaded(SmartPtr<Base1>{});
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~
test.cpp:13:17: note: candidate: ‘static void Overloaded<SmartPtr>::overloaded(const SmartPtr<const Base1>&) [with SmartPtr = QSharedPointer]’
static void overloaded(const SmartPtr<const Base1> &) {}
^~~~~~~~~~
test.cpp:14:17: note: candidate: ‘static void Overloaded<SmartPtr>::overloaded(const SmartPtr<const Base2>&) [with SmartPtr = QSharedPointer]’
static void overloaded(const SmartPtr<const Base2> &) {}
^~~~~~~~~~
test.cpp:21:37: error: call of overloaded ‘overloaded(QSharedPointer<Base2>)’ is ambiguous
Overloaded<SmartPtr>::overloaded(SmartPtr<Base2>{});
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~
test.cpp:13:17: note: candidate: ‘static void Overloaded<SmartPtr>::overloaded(const SmartPtr<const Base1>&) [with SmartPtr = QSharedPointer]’
static void overloaded(const SmartPtr<const Base1> &) {}
^~~~~~~~~~
test.cpp:14:17: note: candidate: ‘static void Overloaded<SmartPtr>::overloaded(const SmartPtr<const Base2>&) [with SmartPtr = QSharedPointer]’
static void overloaded(const SmartPtr<const Base2> &) {}
^~~~~~~~~~
test.cpp:24:37: error: call of overloaded ‘overloaded(QSharedPointer<Child1>)’ is ambiguous
Overloaded<SmartPtr>::overloaded(SmartPtr<Child1>{});
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~
test.cpp:13:17: note: candidate: ‘static void Overloaded<SmartPtr>::overloaded(const SmartPtr<const Base1>&) [with SmartPtr = QSharedPointer]’
static void overloaded(const SmartPtr<const Base1> &) {}
^~~~~~~~~~
test.cpp:14:17: note: candidate: ‘static void Overloaded<SmartPtr>::overloaded(const SmartPtr<const Base2>&) [with SmartPtr = QSharedPointer]’
static void overloaded(const SmartPtr<const Base2> &) {}
^~~~~~~~~~
test.cpp:25:37: error: call of overloaded ‘overloaded(QSharedPointer<Child2>)’ is ambiguous
Overloaded<SmartPtr>::overloaded(SmartPtr<Child2>{});
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~
test.cpp:13:17: note: candidate: ‘static void Overloaded<SmartPtr>::overloaded(const SmartPtr<const Base1>&) [with SmartPtr = QSharedPointer]’
static void overloaded(const SmartPtr<const Base1> &) {}
^~~~~~~~~~
test.cpp:14:17: note: candidate: ‘static void Overloaded<SmartPtr>::overloaded(const SmartPtr<const Base2>&) [with SmartPtr = QSharedPointer]’
static void overloaded(const SmartPtr<const Base2> &) {}
^~~~~~~~~~
test.cpp:26:37: error: call of overloaded ‘overloaded(QSharedPointer<const Child1>)’ is ambiguous
Overloaded<SmartPtr>::overloaded(SmartPtr<const Child1>{});
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~
test.cpp:13:17: note: candidate: ‘static void Overloaded<SmartPtr>::overloaded(const SmartPtr<const Base1>&) [with SmartPtr = QSharedPointer]’
static void overloaded(const SmartPtr<const Base1> &) {}
^~~~~~~~~~
test.cpp:14:17: note: candidate: ‘static void Overloaded<SmartPtr>::overloaded(const SmartPtr<const Base2>&) [with SmartPtr = QSharedPointer]’
static void overloaded(const SmartPtr<const Base2> &) {}
^~~~~~~~~~
test.cpp:27:37: error: call of overloaded ‘overloaded(QSharedPointer<const Child2>)’ is ambiguous
Overloaded<SmartPtr>::overloaded(SmartPtr<const Child2>{});
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~
test.cpp:13:17: note: candidate: ‘static void Overloaded<SmartPtr>::overloaded(const SmartPtr<const Base1>&) [with SmartPtr = QSharedPointer]’
static void overloaded(const SmartPtr<const Base1> &) {}
^~~~~~~~~~
test.cpp:14:17: note: candidate: ‘static void Overloaded<SmartPtr>::overloaded(const SmartPtr<const Base2>&) [with SmartPtr = QSharedPointer]’
static void overloaded(const SmartPtr<const Base2> &) {}
Note how std::shared_ptr doesn't trigger any compile warning and works as expected.
| For Gerrit Dashboard: QTBUG-75222 | ||||||
|---|---|---|---|---|---|---|
| # | Subject | Branch | Project | Status | CR | V |
| 272844,13 | Q{Shared,Weak}Pointer: Reduce overload sets in implicit conversions | 5.13 | qt/qtbase | Status: MERGED | -1 | 0 |