2015-10-20 5 views
5

Ich möchte ein Makro schreiben, das, wenn es innerhalb einer Klasse erweitert wird, diesen Klassentyp verwendet (speziell als Vorlageargument). Innerhalb Klassenmethode, kann ich diese verwenden:C++ - Gibt es Möglichkeiten, den aktuellen Klassentyp mit invarianter Syntax zu erhalten?

#define METHOD_MACRO int sample_method(void)const {\ 
    return template_struct<this_type<decltype(this)>::type>::index;} 

(this_type ist mein struct, hier ist es gleichbedeutend mit remove_pointer<remove_const<T>>)

Aber wenn ich brauche Klassentyp außerhalb des Verfahrens (für typedef für Klasse Elementzeiger), this Schlüsselwort ist nicht verfügbar; Ich habe versucht, auto für einen Trick mit dem Ableiten des Typs zu verwenden, aber kein Glück hier. Klassen in Frage werden von meiner Klasse geerbt, wenn dies hilfreich sein kann. Ich möchte vermeiden, dass jemand, der mein Makro verwendet, typdedef schreiben muss.

Irgendwelche Ideen?

+2

Verwenden Sie CRTP? Vielleicht können Sie Makros ganz eliminieren ... –

+0

Dies erfordert explizite Bemühungen des Benutzers, die ich so oft wie möglich vermeiden möchte. Interessante Idee, aber nicht ganz da. – Abstraction

+1

@Abstraction Das Eingeben des Namens Ihres Makros erfordert vom Benutzer so viel explizite Anstrengung wie das Erben von einer Klasse mit CRTP :) – Drax

Antwort

4

können Sie den folgenden Trick verwenden:

#define SELF \ 
    static auto helper() -> std::remove_reference<decltype(*this)>::type; \ 
    typedef decltype(helper()) self 

struct A { 
    SELF; 
}; 

Ich erkläre, eine Hilfsfunktion der auto Rückgabetyp verwenden, die mich decltype(*this) als Rückgabetyp zu wissen, zu verwenden, ermöglicht es, nicht das, was der Name der Klasse ist. Dann kann ich decltype(helper()) verwenden, um den Klassentyp im Code zu verwenden. Beachten Sie, dass die Funktion static sein muss, andernfalls können Sie sie nicht in decltype verwenden. Auch die Funktion ist nur deklariert, nicht definiert; Das sollte kein Problem sein, da Sie es sowieso nicht nennen werden. (Sie können einen leeren Körper, um es hinzuzufügen, aber es wird eine Warnung zu erhöhen, die eine Funktion keine return hat. Dennoch können Sie den Rückgabetyp ändern decltype(this) zu sein und nullptr zurückzukehren.)

Sie dann die self typedef verwenden kann weitere Deklarationen, oder ändern Sie einfach die Makros zu typedef nicht die Klasse selbst, aber was Sie brauchen. Passen Sie es an Ihre speziellen Bedürfnisse an.

UPD: Dies scheint ein Nicht-Standard-Verhalten von GCC zu sein. Zum Beispiel erlaubt die ICC nicht this in static Funktionen sogar im schleppenden Rückgabetyp.

+2

Warum können Sie 'this' in diesem Kontext verwenden? –

+0

@ n.m., Warum kann ich nicht? Ich bin kein Experte in der Norm, aber mein grobes Verständnis ist, dass "dies" nur ein impliziter Funktionsparameter ist, und ich Funktionsparameter im Rückgabetyp mit "Auto" verwenden kann. Und es funktioniert: http://coliru.stacked-crooked.com/a/9af8022707a13ff6 – Petr

+0

@ n.m., Obwohl ich gerade, dass es tatsächlich seltsam ist, 'this 'in einer' statischen' Funktion zu haben. War am Anfang versucht, es als nicht-statisch zu machen, fügte "statisch" hinzu, um 'declltype (helper())' zu arbeiten, und erkannte nicht, dass 'declltype (* this)' brechen könnte. Wie auch immer, es funktioniert. Sagen Sie nicht, es ist GCC's Bug :) – Petr

Verwandte Themen