Using template on a QWidget constructor
-
Hello everyone. I have created a QWidget class that should take a template pointer as an input. Doing so with a method works fine, however when I try to use it on the QWidget's constructor I get an error. Here's the code:
#ifndef GADGET_H #define GADGET_H #include <QObject> struct P2D { Q_GADGET Q_PROPERTY(P2D p2d READ getP2D ) Q_PROPERTY(float m_x READ getX WRITE setX) Q_PROPERTY(float m_y READ getY WRITE setY) P2D getP2D() {return *this;} float getX() {return this->m_x;} void setX(float x) {this->m_x = x;} float getY() {return this->m_y;} void setY(float y) {this->m_y = y;} public: float m_x; float m_y; }; Q_DECLARE_METATYPE(P2D) #endif
Here's my main:
#include "mainwindow.h" #include "gadget.h" #include <QApplication> #include <QDebug> #include <QMetaObject> #include <QMetaProperty> #include <QVariant> #include <QWidget> #include "objectintrospector.h" int main(int argc, char *argv[]) { QApplication a(argc, argv); qRegisterMetaType<P2D>(); P2D point; point.m_x = 10; point.m_y = 25; objectIntrospector *oi = new objectIntrospector(nullptr, "P2D", &point); oi->show(); return a.exec(); }
And here is my QWidget:
#ifndef OBJECTINTROSPECTOR_H #define OBJECTINTROSPECTOR_H #include <QWidget> class objectIntrospector : public QWidget { Q_OBJECT public: template <class T>objectIntrospector(QWidget *parent = nullptr, const char* typeName = nullptr, T *ptr = nullptr); ~objectIntrospector(); private: Ui::objectIntrospector *ui; };
I get the following error:
undefined reference to `objectIntrospector::objectIntrospector<P2D>(QWidget*, char const*, P2D*)'
Is there a way to use a template on QWidget's constructor?
Thanks for your time.
-
@raphasauer said in Using template on a QWidget constructor:
Is there a way to use a template on QWidget's constructor?
You would also get this function when you don't derive from QWidget since you nowhere define and instantiate
objectIntrospector<P2D >::objectIntrospector(QWidget* const char* T*)
. -
@Christian-Ehrlicher is it a problem with instantiating? Because I can get functions like this to run just fine:
template <class T> const QMetaObject* metaConverter(T* ptr) { const QMetaObject *mo = &ptr->staticMetaObject; return mo; }
I was thinking that I could use the template on the constructor in a similar way.
-
@raphasauer said in Using template on a QWidget constructor:
I was thinking that I could use the template on the constructor in a similar way.
You can but you do not in your example.
-
@Christian-Ehrlicher What would be the proper way to do it? I am resorting to templates because the constructor should receive a generic pointer to an object that contains a Q_GADGET. Or is there a better approach?
-
As for any other template - make the implementation visible to the compiler when it instantiates the template as you did in your second example.
-
@Christian-Ehrlicher by implementation you are referring to
objectIntrospector::objectIntrospector<P2D>(QWidget*, char const*, P2D*)
?
I wasn't using an explicit implementation because "P2D" could be any element that has a Q_GADGET on it. -
I never said you should do this. I said the compiler must see the code when it instantiates the template. Basic c++ stuff.
-
@Christian-Ehrlicher thanks! My C++ is a bit rusty, but I understand what you are saying now.
Basically I should declare the logic with the header, this way the compiler sees that there is an implementation.
-
Correct.