Odpowiedzi:
Ma podobną składnię, z tym wyjątkiem, że usuwasz identyfikator ze wskaźnika:
using FunctionPtr = void (*)();
Oto przykład
Jeśli chcesz „zabrać brzydotę”, wypróbuj sugestie Xeo:
#include <type_traits>
using FunctionPtr = std::add_pointer<void()>::type;
A oto kolejne demo .
:(
using FunctionPtr = AddPointer<void()>;
)
add_pointer<void()>::type
: Korzystając z sugestii tutaj: groups.google.com/a/isocpp.org/d/msg/std-proposity/xDQR3y5uTZ0/ ... możesz pisać pointer<function<void>>
.
„Brzydota” może też zostać usunięta, jeśli unikniesz wpisywania wskaźnika:
void f() {}
using Function_t = void();
Function_t* ptr = f;
ptr();
*
później i dostanę mylące błędy.
Chcesz plik type-id
, który jest w zasadzie dokładnie taki sam jak deklaracja, z wyjątkiem usunięcia pliku declarator-id
. declarator-id
Jest zazwyczaj identyfikator oraz nazwę jesteś deklarując w equivilant deklaracji.
Na przykład:
int x
declarator-id
Jest x
tak po prostu usunąć go:
int
Również:
int x[10]
Usuń x
:
int[10]
Na przykład:
void (*FunctionPtr)()
Oto declarator-id
jest FunctionPtr
. więc po prostu usuń go, aby uzyskać type-id
:
void (*)()
To działa, ponieważ biorąc pod uwagę type-id
, zawsze możesz jednoznacznie określić, gdzie identyfikator miałby się udać, aby utworzyć deklarację. Od 8.1.1 w standardzie:
Możliwe jest jednoznaczne zidentyfikowanie lokalizacji w [id-typie], w której pojawiłby się identyfikator, gdyby konstrukcja była [deklaracją]. Nazwany typ jest wtedy taki sam jak typ hipotetycznego identyfikatora.
A co z tą składnią dla jasności? (Uwaga podwójny nawias)
void func();
using FunctionPtr = decltype((func));
Innym podejściem może być użycie typu automatycznego zwracania z końcowym typem powrotu.
using FunctionPtr = auto (*)(int*) -> void;
Ma to sporną zaletę polegającą na tym, że można powiedzieć, że coś jest funkcją ptr, gdy alias zaczyna się od „auto (*)” i nie jest to zaciemniane przez nazwy identyfikatorów.
Porównać
typedef someStructureWithAWeirdName& (FunctionPtr*)(type1*, type2**, type3<type4&>);
z
using FunctionPtr = auto (*)(type1*, type2**, type3<type4&>) -> someStructureWithAWeirdName&;
Uwaga: zaczerpnąłem to z wykładu Beana Deane'a „Easing into Modern C ++”
using
istocie bardzo conf , zwłaszcza, że identyfikatory wskaźników funkcji zwykle znajdowały się w środkutypedef
instrukcji i przesuwały się na początek za pomocąusing
. Przynajmniej tam się zgubiłem.