Template of QObject* conversation error C2234
-
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; }; }
-
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-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-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-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 atGenericModel::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-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 atGenericModel::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".
-
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. -
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.@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) .... }
-
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? -
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?@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-Kawa
Shit, you are right. I've forgotten the public keyword.
Thanks a lot.
Is there a way to check these things automatically?@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.
-
If someone is interested in a generic list example for c++ and QML, enclosed the link.