Details
-
Bug
-
Resolution: Done
-
P2: Important
-
None
-
5.12.2
-
None
-
gcc 8.2.1, arch
-
-
014d7ac65417ed9b5ffb85cca24d16564ff5005a (qt/qtbase/5.13)
Description
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.