Sehr sicher using, vor allem, weil sich Funktionszeiger- IDs normalerweise in der Mitte einer typedefAnweisung befanden und mit nach vorne verschoben wurden using. Zumindest bin ich dort verloren.
Starturtle
Antworten:
180
Es hat eine ähnliche Syntax, außer dass Sie den Bezeichner aus dem Zeiger entfernen:
Diese Typ-Aliase ändern die Typensyntax von obskurer Inside-Out-Syntax zu einer einfachen Syntax von links nach rechts, wodurch benutzerdefinierte Typedefs für bestimmte APIs, die das Schreiben der zusammengesetzten Typen dieser API erleichtern, weitgehend entfallen.
Bames53
10
In C ++ 14 können Sie schreiben: using FunctionPtr = std :: add_pointer_t <void ()>;
Andrzej
46
Die "Hässlichkeit" kann auch beseitigt werden, wenn Sie die Eingabe eines Zeigers vermeiden:
Dies ist ein interessanter Ansatz, obwohl ich befürchten könnte, den *späteren zu vergessen und verwirrende Fehler zu bekommen.
Apollys unterstützt Monica
Dies ist definitiv die schönste Version, die hier vorgestellt wird. Danke dir. Und ich bevorzuge es, einen Zeiger zu sehen, da es sich schließlich um einen Funktionszeiger handelt.
Pierre
13
Sie möchten eine type-id, die im Wesentlichen genau der Deklaration entspricht, außer dass Sie die löschen declarator-id. Dasdeclarator-id ist normalerweise eine Kennung und der Name, den Sie in der gleichberechtigten Erklärung deklarieren.
Beispielsweise:
int x
Das declarator-idist xso einfach entfernen:
int
Gleichfalls:
int x[10]
Entfernen Sie die x:
int[10]
Für Ihr Beispiel:
void(*FunctionPtr)()
Hier declarator-idist das FunctionPtr. Entfernen Sie es einfach, um Folgendes zu erhalten type-id:
void(*)()
Dies funktioniert, da type-idSie mit a immer eindeutig bestimmen können, wohin der Bezeichner gehen soll, um eine Deklaration zu erstellen. Ab 8.1.1 im Standard:
Es ist möglich, den Ort in der [Typ-ID] eindeutig zu identifizieren, an dem der Bezeichner erscheinen würde, wenn die Konstruktion eine [Deklaration] wäre. Der benannte Typ ist dann der gleiche wie der Typ des hypothetischen Bezeichners.
Was bedeutet die doppelte Klammer in diesem Zusammenhang? Ein Verweis auf einen Funktionszeiger?
0x499602D2
5
Ihr FunctionPtrist kein Funktionszeiger, aber decltype(&f)siehe hier .
Rubenvb
@ 1234597890 FunctionPtr ist eine nicht konstante Wertreferenz auf den Typ 'void ()'
Leo Goodstadt
@rubenvb: Du hast recht. Es ist kein Funktionszeiger, sondern ein Wertverweis auf die Funktion (Typ). Aus diesem Grund schlägt static_assert fehl ... <br/> Versuchen Sie es mit FunctionPtr: using namespace std; #include <iostream> void do_f () {cerr << "what? \ n"; } void f (); using FunctionPtr = decltype ((f)); using FunctionPtr2 = decltype (& f); // Funktioniert nicht // mit FunctionPtr3 = decltype (f); int main () {FunctionPtr ff = do_f; ff (); FunctionPtr2 ff2 = do_f; ff2 (); }
Leo Goodstadt
1
Ein anderer Ansatz könnte die Verwendung des automatischen Rückgabetyps mit dem nachfolgenden Rückgabetyp verwenden.
usingFunctionPtr=auto(*)(int*)->void;
Dies hat den fraglichen Vorteil, dass man sagen kann, dass etwas eine Funktion ptr ist, wenn der Alias mit "auto (*)" beginnt und nicht durch die Bezeichnernamen verschleiert wird.
using
, vor allem, weil sich Funktionszeiger- IDs normalerweise in der Mitte einertypedef
Anweisung befanden und mit nach vorne verschoben wurdenusing
. Zumindest bin ich dort verloren.Antworten:
Es hat eine ähnliche Syntax, außer dass Sie den Bezeichner aus dem Zeiger entfernen:
Hier ist ein Beispiel
Wenn Sie "die Hässlichkeit wegnehmen" möchten, versuchen Sie, was Xeo vorgeschlagen hat:
Und hier ist eine weitere Demo .
quelle
:(
using FunctionPtr = AddPointer<void()>;
;)add_pointer<void()>::type
: Verwenden Sie den Vorschlag hier: groups.google.com/a/isocpp.org/d/msg/std-proposals/xDQR3y5uTZ0/…, den Sie schreiben könnenpointer<function<void>>
.Die "Hässlichkeit" kann auch beseitigt werden, wenn Sie die Eingabe eines Zeigers vermeiden:
http://ideone.com/e1XuYc
quelle
*
späteren zu vergessen und verwirrende Fehler zu bekommen.Sie möchten eine
type-id
, die im Wesentlichen genau der Deklaration entspricht, außer dass Sie die löschendeclarator-id
. Dasdeclarator-id
ist normalerweise eine Kennung und der Name, den Sie in der gleichberechtigten Erklärung deklarieren.Beispielsweise:
Das
declarator-id
istx
so einfach entfernen:Gleichfalls:
Entfernen Sie die
x
:Für Ihr Beispiel:
Hier
declarator-id
ist dasFunctionPtr
. Entfernen Sie es einfach, um Folgendes zu erhaltentype-id
:Dies funktioniert, da
type-id
Sie mit a immer eindeutig bestimmen können, wohin der Bezeichner gehen soll, um eine Deklaration zu erstellen. Ab 8.1.1 im Standard:quelle
Wie wäre es mit dieser Syntax für Klarheit? (Beachten Sie doppelte Klammern)
quelle
FunctionPtr
ist kein Funktionszeiger, aberdecltype(&f)
siehe hier .Ein anderer Ansatz könnte die Verwendung des automatischen Rückgabetyps mit dem nachfolgenden Rückgabetyp verwenden.
Dies hat den fraglichen Vorteil, dass man sagen kann, dass etwas eine Funktion ptr ist, wenn der Alias mit "auto (*)" beginnt und nicht durch die Bezeichnernamen verschleiert wird.
Vergleichen Sie
mit
Haftungsausschluss: Ich habe dies Bean Deanes Vortrag "Easing into Modern C ++" entnommen
quelle