Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Template of QObject* conversation error C2234
Forum Updated to NodeBB v4.3 + New Features

Template of QObject* conversation error C2234

Scheduled Pinned Locked Moved Solved General and Desktop
12 Posts 3 Posters 903 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • K Offline
    K Offline
    Krulle
    wrote on last edited by Krulle
    #1

    Hi,

    I am creating a generic (cpp) listmodel inspired by first repo and second repo.
    Since templates cannot be applied to a QObject-derived class, a small diversions must be taken via a wrapper (GenericListModel).
    The problem is that the compiler throw an Error "C2234: 'conversion type': conversion from 'T*' to 'QObject*' exists, but is inaccessible" -> qmetatype.h line 843.
    I think (and is marked by the compiler) the error is in the template function: GenericListModel::append(T* item).
    Does anyone know why that happend?

    usage:

    class Model: public GenericList::GenericListModel<Item>
    {
        Q_OBJECT
    
    public:
        explicit Model(QObject *parent = nullptr);
    
    
    public slots:
        void append(const QString &name) {
            GenericListModel::append(new Item("foo"));
        };
        bool removeAt(int i);
    };
    

    genericlistmodel.h

    #include "genericitemlist.h"
    #include <QAbstractListModel>
    #include <QDebug>
    
    //Q_MOC_INCLUDE("genericitemlist.h")
    
    namespace GenericList {
    
        static const QModelIndex ROOT_MODEL_INDEX;
    
        class GenericModel : public QAbstractListModel
        {
            Q_OBJECT
            Q_PROPERTY(GenericItemList *itemList READ itemList WRITE setItemList)
        public:
            explicit GenericModel(QObject *parent = nullptr);
    
        protected:
            // implement new functions
            void append(QObject *item);
            bool removeAt(int i);
        };
    
        template <typename T>
        class GenericListModel : public GenericModel
        {
        public:
            explicit GenericListModel(QObject *parent) :
                GenericModel(parent) {}
    
            void append(T *item) {
                GenericModel::append(item); // <- Error
            }
            bool removeAt(int i) { return GenericModel::removeAt(i); }
        };
    }
    

    genericitemlist.h

    namespace GenericList {
    
        class GenericItemList : public QObject
        {
            Q_OBJECT
    
        public:
            explicit GenericItemList(QObject *parent = nullptr);
            ~GenericItemList();
    
            QVector<QObject *> items() const;
    
            // implement new functions
            void appendItem(QObject *item);
            bool removeItemAt(int i);
    
        private:
            QVector<QObject *> m_itemList;
        };
    
    }
    
    J.HilkJ 1 Reply Last reply
    0
    • K Krulle

      Hi,

      I am creating a generic (cpp) listmodel inspired by first repo and second repo.
      Since templates cannot be applied to a QObject-derived class, a small diversions must be taken via a wrapper (GenericListModel).
      The problem is that the compiler throw an Error "C2234: 'conversion type': conversion from 'T*' to 'QObject*' exists, but is inaccessible" -> qmetatype.h line 843.
      I think (and is marked by the compiler) the error is in the template function: GenericListModel::append(T* item).
      Does anyone know why that happend?

      usage:

      class Model: public GenericList::GenericListModel<Item>
      {
          Q_OBJECT
      
      public:
          explicit Model(QObject *parent = nullptr);
      
      
      public slots:
          void append(const QString &name) {
              GenericListModel::append(new Item("foo"));
          };
          bool removeAt(int i);
      };
      

      genericlistmodel.h

      #include "genericitemlist.h"
      #include <QAbstractListModel>
      #include <QDebug>
      
      //Q_MOC_INCLUDE("genericitemlist.h")
      
      namespace GenericList {
      
          static const QModelIndex ROOT_MODEL_INDEX;
      
          class GenericModel : public QAbstractListModel
          {
              Q_OBJECT
              Q_PROPERTY(GenericItemList *itemList READ itemList WRITE setItemList)
          public:
              explicit GenericModel(QObject *parent = nullptr);
      
          protected:
              // implement new functions
              void append(QObject *item);
              bool removeAt(int i);
          };
      
          template <typename T>
          class GenericListModel : public GenericModel
          {
          public:
              explicit GenericListModel(QObject *parent) :
                  GenericModel(parent) {}
      
              void append(T *item) {
                  GenericModel::append(item); // <- Error
              }
              bool removeAt(int i) { return GenericModel::removeAt(i); }
          };
      }
      

      genericitemlist.h

      namespace GenericList {
      
          class GenericItemList : public QObject
          {
              Q_OBJECT
      
          public:
              explicit GenericItemList(QObject *parent = nullptr);
              ~GenericItemList();
      
              QVector<QObject *> items() const;
      
              // implement new functions
              void appendItem(QObject *item);
              bool removeItemAt(int i);
      
          private:
              QVector<QObject *> m_itemList;
          };
      
      }
      
      J.HilkJ Offline
      J.HilkJ Offline
      J.Hilk
      Moderators
      wrote on last edited by
      #2

      @Krulle GenericModel::append expects an explicit QObject * you're giving it a template type. that won't work.

      cast it explicitly to an QObject pointer beforehand.


      Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


      Q: What's that?
      A: It's blue light.
      Q: What does it do?
      A: It turns blue.

      1 Reply Last reply
      0
      • K Offline
        K Offline
        Krulle
        wrote on last edited by
        #3

        @J-Hilk thanks for you're answer.

        And how?

        void append(T *item) {
                GenericModel::append(qobject_cast<QObject*>(item));
        }
        

        won't work.

        void append(T *item) {
                GenericModel::append(dynamic_cast<QObject*>(item));
        }
        

        shows warnings and C2243 hikes to "qmetatype.h 843" and is hidden by moc_model.cpp

        J.HilkJ 1 Reply Last reply
        0
        • K Krulle

          @J-Hilk thanks for you're answer.

          And how?

          void append(T *item) {
                  GenericModel::append(qobject_cast<QObject*>(item));
          }
          

          won't work.

          void append(T *item) {
                  GenericModel::append(dynamic_cast<QObject*>(item));
          }
          

          shows warnings and C2243 hikes to "qmetatype.h 843" and is hidden by moc_model.cpp

          J.HilkJ Offline
          J.HilkJ Offline
          J.Hilk
          Moderators
          wrote on last edited by
          #4

          @Krulle you're working with templates here -> no qt safety net -> use static_cast


          Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


          Q: What's that?
          A: It's blue light.
          Q: What does it do?
          A: It turns blue.

          K 1 Reply Last reply
          0
          • J.HilkJ J.Hilk

            @Krulle you're working with templates here -> no qt safety net -> use static_cast

            K Offline
            K Offline
            Krulle
            wrote on last edited by
            #5

            @J-Hilk
            it's the same than no cast, what I had also expected. Because as I understand it, the compiler should do an implicit cast.
            A dynamic cast eliminates the compiler error at

            GenericModel::append(dynamic_cast<QObject*>(item));
            

            but shows a lot of warnings.
            Maybe i should go back and start a new try to be able to understand the problem better.

            i'll try to implement the generic model at the qt-tutorial "todolist".

            J.HilkJ 1 Reply Last reply
            0
            • K Krulle

              @J-Hilk
              it's the same than no cast, what I had also expected. Because as I understand it, the compiler should do an implicit cast.
              A dynamic cast eliminates the compiler error at

              GenericModel::append(dynamic_cast<QObject*>(item));
              

              but shows a lot of warnings.
              Maybe i should go back and start a new try to be able to understand the problem better.

              i'll try to implement the generic model at the qt-tutorial "todolist".

              J.HilkJ Offline
              J.HilkJ Offline
              J.Hilk
              Moderators
              wrote on last edited by
              #6

              @Krulle mmh, fair enough. What about the good old "compiler trust me" c-style cast ?


              Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


              Q: What's that?
              A: It's blue light.
              Q: What does it do?
              A: It turns blue.

              1 Reply Last reply
              0
              • Chris KawaC Offline
                Chris KawaC Offline
                Chris Kawa
                Lifetime Qt Champion
                wrote on last edited by
                #7

                What is the Item type? The error says it can't convert it, so I would start there instead of shady casts. If it's derived from QObject the pointer cast should be automatic.

                K 1 Reply Last reply
                0
                • Chris KawaC Chris Kawa

                  What is the Item type? The error says it can't convert it, so I would start there instead of shady casts. If it's derived from QObject the pointer cast should be automatic.

                  K Offline
                  K Offline
                  Krulle
                  wrote on last edited by
                  #8

                  @Chris-Kawa
                  The Item is a QObject class only with propertys:

                  class Item: public QObject
                  {
                      Q_OBJECT
                  
                      Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
                  ....
                  }
                  
                  1 Reply Last reply
                  0
                  • Chris KawaC Offline
                    Chris KawaC Offline
                    Chris Kawa
                    Lifetime Qt Champion
                    wrote on last edited by
                    #9

                    Are you sure you're inheriting QObject publicly i.e. it's not class Item: QObject? Do you have Item type include in the place of that template instantiation and not just forward declaration?

                    K 1 Reply Last reply
                    2
                    • Chris KawaC Chris Kawa

                      Are you sure you're inheriting QObject publicly i.e. it's not class Item: QObject? Do you have Item type include in the place of that template instantiation and not just forward declaration?

                      K Offline
                      K Offline
                      Krulle
                      wrote on last edited by
                      #10

                      @Chris-Kawa
                      Shit, you are right. I've forgotten the public keyword.
                      Thanks a lot.
                      Is there a way to check these things automatically?

                      Chris KawaC 1 Reply Last reply
                      0
                      • K Krulle

                        @Chris-Kawa
                        Shit, you are right. I've forgotten the public keyword.
                        Thanks a lot.
                        Is there a way to check these things automatically?

                        Chris KawaC Offline
                        Chris KawaC Offline
                        Chris Kawa
                        Lifetime Qt Champion
                        wrote on last edited by
                        #11

                        @Krulle said:

                        Is there a way to check these things automatically?

                        It's not an error in terms of syntax. There are valid use cases for private inheritance. Automation can't know if you meant it or not.

                        1 Reply Last reply
                        0
                        • K Offline
                          K Offline
                          Krulle
                          wrote on last edited by
                          #12

                          If someone is interested in a generic list example for c++ and QML, enclosed the link.

                          1 Reply Last reply
                          0

                          • Login

                          • Login or register to search.
                          • First post
                            Last post
                          0
                          • Categories
                          • Recent
                          • Tags
                          • Popular
                          • Users
                          • Groups
                          • Search
                          • Get Qt Extensions
                          • Unsolved