Anwesenheit eines beliebigen Mitglieds erkennen

8

Es ist einfach, eine Vorlage zu schreiben, die das Vorhandensein eines bestimmten Mitglieds innerhalb eines Typs mit void_t erkennt:

%Vor%

Wenn ich nun feststellen möchte, ob ein anderes Mitglied vorhanden ist, müsste ich die Detektorvorlagen kopieren und einfügen und einfach aMember in otherMember ändern:

%Vor%

Ich möchte dieses Kopieren-Einfügen vermeiden und den Mitgliedsnamen als Parameter an eine allgemeinere Version der Erkennungsvorlage übergeben:

%Vor%

, so dass ich diese has_arbitrary_member verwenden könnte, indem ich den Typ und den Mitgliedsnamen als Vorlagenparameter übergebe:

%Vor%

Mit der Definition, die ich oben entworfen habe, wird dies jedoch nicht kompiliert. Gibt es eine andere Möglichkeit, diese Funktionalität zu implementieren?

    
Rostislav 13.10.2015, 17:44
quelle

2 Antworten

7

Was Sie zu tun versuchen, ist im Allgemeinen nicht möglich, weil ist, wenn Sie den Token-Stream nicht mithilfe eines Makros ändern. Daraus folgt, dass Sie niemals einen Namen verwenden können, der nicht im Gültigkeitsbereich liegt, es sei denn, Sie befinden sich derzeit innerhalb von SFINAE, wodurch der Fehler unterdrückt wird.

Dies bedeutet, dass Sie wirklich eine separate Vorlage für jeden Namen schreiben müssen.

Dies ist einer der Fälle, in denen die Verwendung von Makros keine schlechte Idee ist, obwohl das davon abhängt, ob Sie wirklich nach Mitgliedern eines bestimmten Namens suchen müssen oder ob es bessere Möglichkeiten gibt, Ihr Ziel zu erreichen.

>     
Brian 13.10.2015, 18:03
quelle
3

Nein, Sie können keinen Member-Namen als Template-Parameter übergeben, ohne zu erwähnen, aus welcher Klasse / Struktur der Member-Name stammt.

Und wenn diese Klasse / Struktur diesen Membernamen nicht hat, dann hat der Code einen Fehler.

Nun ist void_t< decltype( &MyType::some_member ) > entweder void oder ein Substitutionsfehler, abhängig davon, ob some_member existiert. Das löst häufig ein SFINAE-Problem, bei dem Sie keine boole Kompilierzeit benötigen.

Wenn Code ausgeführt werden soll, wenn ein Typ nicht ein Member hat, können Sie dies mit einer sorgfältigen Auswahl der Überladungsreihenfolge oder der Vorlagenspezialisierung usw. tun.

Es ist nicht so mächtig wie has_arbitrary_member<MyType, some_member> .

%Vor%

ist ein einfaches Merkmal, das Sie mit std :: experimental :: is_detected tun können:

%Vor%

oder

%Vor%

was sich wie has_arbitrary_member<MyType, some_member> verhält. Ich finde das in der Praxis am besten.

    
Yakk 13.10.2015 18:03
quelle

Tags und Links