Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-75222

ambiguous QSharedPointer overloads with polymorphic base class

    XMLWordPrintable

Details

    • Bug
    • Resolution: Done
    • P2: Important
    • None
    • 5.12.2
    • None
    • gcc 8.2.1, arch
    • All
    • 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.

      Attachments

        For Gerrit Dashboard: QTBUG-75222
        # Subject Branch Project Status CR V

        Activity

          People

            thiago Thiago Macieira
            milianw Milian Wolff
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes