Bei der Codeentwicklung ist es oft notwendig, das Vorhandensein bestimmter Mitgliedsvariablen innerhalb einer Klasse zu bestimmen. Diese Informationen sind besonders nützlich für die Erstellung generischer Algorithmus-Vorlagenfunktionen, die auf verschiedenen Klassen mit unterschiedlichen Mitgliedsnamen arbeiten.
Bei einer gegebenen Klasse als Vorlagenargument besteht das Ziel darin, festzustellen, ob dies der Fall ist besitzt eine bestimmte Mitgliedsvariable, die entweder durch „x“ oder „X“ (oder deren Gegenstücke in Großbuchstaben) gekennzeichnet ist. Diese Funktion würde die Erstellung generischer Algorithmen erleichtern, die verschiedene Koordinatensysteme verarbeiten, wie z. B. die CPoint-Klassen von MFC oder die PointF-Klassen von GDI.
Um dieses Problem zu beheben, kann eine Vorlage implementiert werden akzeptiert eine Klasse als Vorlagenargument und prüft, ob die gewünschte Mitgliedsvariable vorhanden ist. Durch die Nutzung der Größe von Operator- und Typmerkmalen ist es möglich, zwischen der Existenz von „x“- und „X“-Mitgliedsvariablen zu unterscheiden.
Hier ist eine Beispielimplementierung:
template<int> struct TT { typedef int type; }; template<class P> bool Check_x(P p, typename TT<sizeof(&P::x)>::type b = 0) { return true; } template<class P> bool Check_x(P p, typename TT<sizeof(&P::X)>::type b = 0) { return false; }
Diese Vorlage funktioniert durch Vergleich der Größe von &P::x und &P::X, um zu bestimmen, welche Mitgliedsvariable vorhanden ist. Wenn &P::x vorhanden ist, gibt die Vorlage true zurück; andernfalls wird false zurückgegeben.
Die vorgeschlagene Lösung ist sowohl mit Visual Studio als auch mit GNU C kompatibel. Für einen universelleren Ansatz kann jedoch eine Lösung verwendet werden, die Merkmale vom Typ C 11 verwendet:
#include <type_traits> template <typename T, typename = int> struct HasX : std::false_type { }; template <typename T> struct HasX<T, decltype((void) T::x, 0)> : std::true_type { };
Diese Lösung nutzt die Merkmale vom Typ decltype und std::false_type, um das Vorhandensein von x in der gegebenen Klasse zu erkennen . Wenn T eine x-Mitgliedsvariable hat, ist HasX
Um die Verwendung der HasX-Vorlage zu demonstrieren:
struct A { int x; }; struct B { int y; }; int main() { std::cout << std::boolalpha << HasX<A>::value << std::endl; // true std::cout << std::boolalpha << HasX<B>::value << std::endl; // false return 0; }