Ich möchte überprüfen, ob eine Membervariable einer Klasse statisch ist oder nicht. Die Verwendung von std :: is_member_pointer funktioniert für alle Typen mit Ausnahme von Referenzmembern.
%Vor%Ich verstehe den Fehler, dass ein Zeiger nicht auf ein Referenzelement zeigen kann. Aber wie kann man es vermeiden und trotzdem unterscheiden, ob es sich um eine statische oder nicht statische Variable handelt? Irgendeine Idee dazu?
Sie könnten ein Fallback hinzufügen, falls &E::foo
mit SFINAE fehlschlägt (und ein weiteres, falls E::foo
gar nicht existiert):
Was dieser Code macht:
&T::foo
gültig ist, wird geprüft, ob das Mitglied statisch ist oder nicht std::is_member_pointer
(Ihre Version) verwendet. &T::foo
nicht gültig ist, fällt es auf die zweite Überladung zurück (hier sind Sie sicher, dass foo
nicht statisch ist oder die erste Überladung gewählt wurde):
T::foo
gültig ist (ein Mitglied existiert), wird std::true_type
. std::false_type
zurück. Beachten Sie auch (dank @iammilind), dass für private
member, T::foo
nicht gültig ist, daher wird die dritte Überladung gewählt.
Arbeitsbeispiel für ideone: Ссылка
Seitliche Notizen (erweiterte Erklärung):
&T::foo
gültig ist, sind die beiden ersten Überladungen gültig, aber die erste wird ausgewählt, da int
eine exakte Übereinstimmung ist, während long
nicht. decltype(T::foo, std::true_type{})
: T::foo
ist nur hier, um "SFINAE" auf die dritte Überladung zurückfallen zu lassen, wenn T::foo
nicht gültig ist, aber der resultierende Typ ist std::true_type
dank des Komma-Operators. Wenn Sie möchten, können Sie auch eine generische Version ( Ссылка ) erstellen:
%Vor% Siehe auch diese zwei Antworten, wenn Sie alles in einer Klasse kapseln möchten (ohne is_member_
-Funktionen):
Tags und Links c++ c++11 reference typetraits