how do I solve the error: specializing member requires 'template<>' syntax?
-
I'm trying to emit a signal from one thread to another, the signal has to emit a custom datatype. The whole contents of my thread class are:
/#ifndef DEVICEPRESENCE_H #define DEVICEPRESENCE_H #include <QThread> #include <QObject> #include <QSerialPortInfo> #include <QList> #include <QMetaType> typedef QList<QSerialPortInfo> AvailablePorts; qRegisterMetaType<AvailablePorts>("AvailablePorts"); class DevicePresence : public QThread { Q_OBJECT public: explicit DevicePresence(QObject *parent = 0); void run(); signals: void devicesChanged(AvailablePorts m_availablePorts); private: AvailablePorts m_availablePorts; }; #endif // DEVICEPRESENCE_H
But when I compile the code I get the error:
devicepresence.h:12: error: specializing member ‘::qRegisterMetaType<AvailablePorts>’ requires ‘template<>’ syntax
qRegisterMetaType<AvailablePorts>("AvailablePorts");
^I'm not really sure what I need to do here, I followed the steps in nt qRegisterMetaType(const char *typeName) which states:
typedef QString CustomString; qRegisterMetaType<CustomString>("CustomString");
So that's what I did.
Am I missing something?
-
@m4l490n said in how do I solve the error: specializing member requires 'template<>' syntax?:
QSerialPortInfo
You can declare a new type using a macro
Q_DECLARE_METATYPE(AvailablePorts)
Code
... typedef QList<QSerialPortInfo> AvailablePorts; Q_DECLARE_METATYPE(AvailablePorts) ...
References
-
@KillerSmath thanks for helping.
When I do that then it compiles fine but when I try to run it I get:
QObject::connect: Cannot queue arguments of type 'AvailablePorts'
(Make sure 'AvailablePorts' is registered using qRegisterMetaType().)
QThread: Destroyed while thread is still running
The program has unexpectedly finished.
The process was ended forcefully. -
Everything is working well to me, but okay, i have some questions:
- Where are you declaring the metatype ?
- Can you show me your connection code ?
-
@KillerSmath I'm declaring it on the "devicepresence.h" header file for my class whose contents I posted on the original question. The connection code is as follows:
connect(devicePrecenseThread, &DevicePresence::devicesChanged, this, &MainWindow::refreshDevicesList);
And in "mainwindow.h" I have the private slot void refreshDevicesList(AvailablePorts availablePorts); as well as the private member DevicePresence *m_devicePrecenseThread;
-
Hi,
IIRC, that error indicates you need to also provide the QDataStream operators for your custom type or at leat forQSerialPortInfo
so that they can be stored into/loaded from QVariant.Wrong memory, the QDataStream operators missing triggers another error clearly stating that the data cannot be loaded/stored with Variants.
-
@KillerSmath and @SGaist After struggling a lot with this I was reading again the int qRegisterMetaType(const char *typeName) documentation and I read that:
"This function is useful to register typedefs so they can be used by QMetaProperty, or in QueuedConnections"
So I thought; well if it is a function it should go inside a method. So I put it in the constructor in the .cpp file:
DevicePresence::DevicePresence(QObject *parent) : QThread(parent) { qRegisterMetaType<AvailablePorts>("AvailablePorts"); }
And now everything is working perfectly fine!!
To be honest, I don't know why it is working now, but this seems much simpler than what @SGaist proposes.
I have no idea why it is working and it would be really useful if someone could please explain why this works to be able to flag that as the correct answer because nevertheless my issue was solved, I don't think this should be closed until I know what happened, also might be helpful if someone else finds the same issue.
Thanks for helping!!
-
Where did you had the original
qRegisterMetaType<AvailablePorts>
call ? -
@SGaist if you see the original question I posted the contents of the devicepresence.h file. I got confused by the documentation and I declared my typedef on line 10 and then I put
qRegisterMetaType<AvailablePorts>("AvailablePorts")
on line 11.So I saw this in the documentation:
typedef QString CustomString; qRegisterMetaType<CustomString>("CustomString");
And I did this in the devicepresence.h file:
typedef QList<QSerialPortInfo> AvailablePorts; qRegisterMetaType<AvailablePorts>("AvailablePorts");
But the documentation doesn't contain any examples that illustrate where you have to put that and since I'm coming from C and I'm used to putting the typedefs in the .h files and I'm not familiar yet with the
<>
notation which confused me into not being sure ifqRegisterMetaType<AvailablePorts>("AvailablePorts")
was a function or not, then I ended up putting it in the devicepresence.h file immediately after the typedef declaration. -
Thanks for the clarification. It's not always clear from posted code whether the example is the current code or some snippet.
In any case, where you call
qRegisterMetaType
depends on how your code is managed (is it a library that you provide, etc.). If it's your own application, you can simply do it in themain
function after you instantiated QApplication. That way you don't lose time calling it again each time you construct aDevicePresence
object.