Suppose that there is a project that uses Qt, and depends on the features (e.g. added class members) present in a new version of Qt. The project is meant to be built with a "system"/distribution version of Qt that may be older than the version the project depends on.
The naive approach results in the preprocessor hell:
void Class::foo() {
#if QT_VERSION >= QT_VERSION_CHECK(...)
QClass::newFangled();
#else
QClass::oldFangled1();
blurble();
#endif
}
Is there a cleaner approach that won't depend on preprocessor macros at the point of use of the feature? I.e. we do not want:
// THIS IS BLAH
#if QT_VERSION >= QT_VERSION_CHECK(...)
#define QClass_newFangled QClass::newFangled
#else
#define QClass_newFangled [this]{ \
QClass::oldFangled1(); \
blurble(); \
}
#endif
void Class::foo() {
QClass_newFangled();
}
A workable approach is to use a given class or global function in a custom namespace. The class/function in that namespace can be imported from Qt without changes, or be the custom one that backports the needed features.
The code below is Qt-namespace-aware: it will work with a namespaced Qt build.
At the point of use, the backported functionality (global functions and classes) are accessed in the
compat
namespace, i.e.Note that when adding functions/methods with default arguments to the
compat
namespace, the default arguments are propagated only in C++17 and later. Otherwise, we have to handle them ourselves by defining forwarding functions/methods.Backporting a global function
Suppose that we want to backport
qEnvironmentVariableIntValue
from Qt 5.5:Backporting into a class
Suppose that we want to backport Qt 5.4's
QTimer::singleShot(int, QObject*, Functor)
, as motivated by this answer: