Skip to content

Instantly share code, notes, and snippets.

@hasselmm
Last active March 6, 2023 10:52
Show Gist options
  • Save hasselmm/9cc5fb4404b52d28560b86cb468ca707 to your computer and use it in GitHub Desktop.
Save hasselmm/9cc5fb4404b52d28560b86cb468ca707 to your computer and use it in GitHub Desktop.
Switch statement on C++ type in Qt
constexpr quint64 label(const char *const s, size_t shift = 0)
{
if (s[0] == '\0')
return 0; // end of string
if (shift == 56)
return 0; // avoid integer overflow
return (static_cast<quint64>(s[0]) << shift) ^ label(&s[1], shift + 1);
}
template<typename T>
constexpr auto label()
{
return label(QMetaType::fromType<T>().name());
}
constexpr auto label(QMetaType metaType)
{
return label(metaType.name());
}
static_assert(label<int>());
static_assert(label<int>() != label<uint>());
void demo(const QObject *obj)
{
switch (label(obj->metaObject()->metaType())) {
case label<QLabel>():
qInfo() << "This is a label";
break;
case label<QButton>():
qInfo() << "This is a button";
break;
}
}
@hasselmm
Copy link
Author

hasselmm commented Mar 6, 2023

Why switch instead of the usual if-else-forest of dynamic casts?

  • Constant-time execution: It's a single lookup, instead a random number of casts, depending on how late the matching cast can be found in your if-else-forest.
  • The compiler detects duplicate in switch statements, which is not supported for if-else-forests.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment