Um eine Fallunterscheidung für einen Parameter zu machen t
vom Typ T
SFINAE verwenden, möchte ich, wenn die Erklärung wissenÜberprüfen Sie, ob Typ als Meta-Typ-System deklariert wird (für SFINAE)
QVariant::fromValue(t);
und/oder
QVariant::value<T>();
kompiliert. Wenn das eine kompiliert, tut das andere auch, es sei denn, Sie hacken das Meta-Typ-System. Sie kompilieren genau dann, wenn T
mit Q_DECLARE_METATYPE(T)
deklariert wurde.
Sehr einfaches Anwendungsbeispiel, wo man den Typ eines Wertes einfach durch qDebugging eines variantenumsponnenen Äquivalents drucken möchte, wenn und nur wenn vom Metatypsystem unterstützt (Ich brauche das nicht, aber das zeigt das Problem in einem minimalen Beispiel):
template<class T> // enable if T NOT registered in the Qt meta type system
void print(const T &t) {
qDebug() << t;
}
template<class T> // enable if T registered in the Qt meta type system
void print(const T &t) {
qDebug() << QVariant::fromValue<T>();
}
ich kenne einige (noch ähnlich) Möglichkeiten, dies zu tun, aber alle von ihnen einige Helfern structs vorstellen, komplizierte enable_if usw. Jetzt weiß ich, dass es QTypeInfo
ist das, wie ich glaube, , bietet bereits so etwas wie ein Typ "ist in der Qt-Meta-Typ-System deklariert" -Typ. Diese Klasse ist jedoch nicht dokumentiert und daher wird sie nicht für die Verwendung in Langzeit- und Produktivcode empfohlen, da sie sich zwischen Qt-Versionen ändern kann.
Gibt es einen sehr einfachen Weg (einfacher als mit einem "checker" + enable_if), um eine SFINAE Spezialisierung einzutragen, wenn ein Typ T
von QVariant unterstützt wird?
Bitte beachten Sie, dass die Lösung immer Portable zwischen verschiedenen Qt-Versionen (Qt4 und Qt5 könnte eine andere QTypeInfo
Definition verwenden). Allerdings verwende ich C++ 11, also habe ich beispielsweise Zugriff auf std::enable_if
.
Der "nicht portable" Weg ist, die interne Definition von QMetaTypeId2<T>::Defined
in einem enable_if
(es ist ein Enum-Wert als entweder 0 oder 1 definiert) zu verwenden. Somit würde eine Arbeitslösung sein:
template<class T>
typename std::enable_if<!QMetaTypeId2<T>::Defined>::type
print(const T &t) {
qDebug() << t;
}
template<class T>
typename std::enable_if<QMetaTypeId2<T>::Defined>::type
print(const T &t) {
qDebug() << QVariant::fromValue<T>();
}
Da jedoch QMetaTypeId2
nicht dokumentiert ist und nur für interne Sachen, sollte es nicht in Client-Code angezeigt.
Korrigieren Sie mich, wenn ich mich irre: Sie wollen in ** Kompilierzeit wissen ** hat einen Typ in Qt-Meta-System in ** Laufzeit ** registriert registriert ??? Wenn ja - es ist Unsinn – borisbn
Nein. Ich meine "deklariert", d. H. Es ist ein "Q_DECLARE_METATYPE (T)" vorhanden. Entschuldigung, ich werde es korrigieren. – leemes
Die nächste, die ich finden kann, ist 'qMetaTypeId()', aber es verursacht einen Compiler-Fehler, wenn 'T' nicht registriert ist - nicht so gut. –
cmannett85