Heise Developer: Dem Elfenbeinturm entreißen

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 T auf den dazugehörigen QVariant-internen Diskriminator abzubilden. Das leistet das Funktions-Template qMetaTypeId() […].

Zweitens ein Weg, um “für jeden Typ T, den T_Variant enthalten 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.

About marcmutz
Marc Mutz is a Senior Software Engineer, Trainer, and Consultant with KDAB.

3 Responses to Heise Developer: Dem Elfenbeinturm entreißen

  1. jjost says:

    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 :]

  2. jjost says:

    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 );

  3. Pingback: Private Practice: Taming Templates « -Wmarc

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: