Heise Developer: Dem Elfenbeinturm entreißen
2010-07-21 3 Comments
A little belatedly, I guess, but here we go:
For you German speakers out there, my first Heise Developer article, “Dem Elfenbeinturm entreißen: Über den praxisrelevanten Einsatz der Template-Metaprogrammierung“, “just” went live on Heise’s site.
It shows how to use TMP to convert from QVariant to boost::variant<>. Even if you don’t speak German, you might be interested in the sample source code: ftp://ftp.heise.de/pub/ix/developer/elfenbein.zip.
From the article:
Als Ansatz für eine Konvertierungsfunktion lässt sich Folgendes schreiben.
template <typename T_Variant> T_Variant qvariant2variant( const QVariant & qv ) { for( T : types(T_Variant) ) if ( qv.type() == T ) return T_Variant( qvariant_cast<T>( qv ) ); throw bad_cast( "..." ); };Es fehlen noch zwei Dinge, um aus dem Pseudocode “richtigen” Code zu erstellen: Erstens ein Weg, um einen Typ
Tauf den dazugehörigen QVariant-internen Diskriminator abzubilden. Das leistet das Funktions-TemplateqMetaTypeId()[...].Zweitens ein Weg, um “für jeden Typ
T, denT_Variantenthalten kann”, abzubilden. Das lässt sich mit TMP lösen (Stichwort: Liste von Typen), was die Aufgabe für den Rest des Artikels sein wird.

Wow, thanks! I’m currentlty working on a project using both QVariant and boost::variant and wondered if there was a generic and elegant way to convert between the two. The boost::variant to QVariant was easy to figure using a boost visitor, but the other way around I wouldn’t have found without your article!
It even allowed me to practise some german since quite a while :]
Mmh, I think there might be a little error in your code if you want it to work properly with user-defined types stored in QVariant ( e.g. defined using Q_DECLARE_METATYPE ) : you shouldn’t compare the metatype of each type using QVariant::type() (which will always return QVariant::UserType for user-defined types) but rather use QVariant::userType() which will return the actual ID of the metatype (== the same value that would be returned by qMetaTypeId ) :
// the static_cast is there to fix a signed/unsigned warning
if ( static_cast( qv.userType() ) == qMetaTypeId() )
return T_Variant( qvariant_cast( qv ) );
else
return qvariant2variant_helper( qv );
Pingback: Private Practice: Taming Templates « -Wmarc