Hello all,
It's my first question there, and it's a noobish question :).
I'm facing to a problem with C++ and Qt 4.6, because I want to factorize some of my code which is invoking some public slots of a QObject, through the QMetaMethod::invoke() method.
The problem I'm facing to, is that the Q_ARG macro is defined as follow:
#define Q_ARG(type, data) QArgument<type >(#type, data)
That says that I should know at compile time the type. But I get on the other hand my arguments for the method, which are coming as QVariants. I can get their types through the ->type() accessor, which returns an enum value of type QVariant::Type, but naturally not as compile time type.
So to simply generates the arguments for the invocation, I made the following macro:
#define PASS_SUPPORTED_TYPE(parameterToFill, requiredType, param, supported) { \
\
switch (requiredType) { \
case QVariant::String: \
parameterToFill = Q_ARG(QString, \
param.value<QString>()); \
break; \
\
case QVariant::Int: \
parameterToFill = Q_ARG(int, param.value<int>()); \
break; \
\
case QVariant::Double: \
parameterToFill = Q_ARG(double, param.value<double>()); \
break; \
\
case QVariant::Char: \
parameterToFill = Q_ARG(char, param.value<char>()); \
break; \
\
case QVariant::Bool: \
parameterToFill = Q_ARG(bool, param.value<bool>()); \
break; \
\
case QVariant::Url: \
parameterToFill = Q_ARG(QUrl, param.value<QUrl>()); \
break; \
\
default: \
supported = false; \
\
} \
\
supported = true; \
}
The same could be done in a method which could return true or false instead of setting the "supported" flag, but this would force me to make heap allocation in this case, because the "param.value()" call returns a copy of the QVariant value, which I should store in heap through a new or through a memset.
And that is my problem, I don't want to do heap allocation in this method, because this will get called thousands of time (this is a request handling module).
for (int k = 0; k < methodParams.size(); ++k) {
QVariant::Type paramType = QVariant::nameToType(methodParams[k].toAscii());
[...]
bool supportedType = false;
PASS_SUPPORTED_TYPE(
paramsToPass[k],
paramType,
params[k],
supportedType);
[...]
}
metaMethod.invoke(objectToCall, paramsToPass[0], paramsToPass[1], paramsToPass[2] [...]);
This does not please me because it's not type safe. So the question I'm asking myself is how could I fire out this macro, and replace it with a method which would do stack allocation and not heap allocation?
I thank you all in advance for your help and interest.