Mache die Ausdrücke fun
und &fun
haben den gleichen Typ oder nicht?
Betrachten Sie den folgenden Code:
template <typename Check, typename T>
void check(T)
{
static_assert(is_same<Check, T>::value);
}
void fun()
{}
check<void(*)()>(fun);
check<void(*)()>(&fun);
cout << typeid(fun).name() << endl;
cout << typeid(&fun).name() << endl;
Beide Aussagen sind erfolgreich, was darauf hindeutet, dass beide Ausdrücke denselben Typ haben. typeid
s gibt jedoch unterschiedliche Ergebnisse zurück:
FvvE
PFvvE
Warum das?
Beide Zusicherungen sind erfolgreich, da sie auf den vom Funktionsargument abgeleiteten Typ T
angewendet werden. In beiden Fällen wird es als Zeiger auf Funktion hergeleitet, da Funktionen in einen Zeiger auf Funktion zerfallen. Wenn Sie jedoch Zusicherungen neu schreiben, um Typen direkt zu akzeptieren, schlägt die erste fehl:
static_assert(is_same<void(*)(), decltype(fun)>::value);
static_assert(is_same<void(*)(), decltype(&fun)>::value);
fun
und &fun
beziehen sich auf denselben Typ, da Konvertierung von Funktion in Zeiger in check<void(*)()>(fun);
; aber typeid
ist eine Ausnahme.
(Hervorhebung von mir)
LWert-zu-rWert-, Array-zu-Zeiger- oder Funktions-zu-Zeiger-Konvertierungen werden nicht durchgeführt .
Und warum die Konvertierung von Funktion in Zeiger für check<void(*)()>(fun);
ausgeführt wird, weil in Template-Argument-Abzug ,
Bevor der Abzug beginnt, werden die folgenden Anpassungen an [~ # ~] p [~ # ~] und [~ # ~] a [~ # ~] werden gemacht:
1) Wenn [~ # ~] p [~ # ~] kein Referenztyp ist,
- if [~ # ~] a [~ # ~] ist ein Array-Typ, ...;
- andernfalls, wenn [~ # ~] ein [~ # ~] ein Funktionstyp ist, [~ # ~ ] ein [~ # ~] wird durch den Zeigertyp ersetzt, der durch die Umwandlung von Funktion in Zeiger erhalten wird;
check()
nimmt Parameter nach Wert, dann wird eine Funktion-Zeiger-Umwandlung durchgeführt und der abgeleitete Typ von T
wird auch der Funktionszeiger sein, d. h. void(*)()
.
Wenn Sie einen Funktionsnamen als Ausdruck verwenden, wird zerfällt auf einen Zeiger auf sich selbst verwiesen. Also ist fun
dasselbe wie &fun
.
Wie für die Sache typeid
von diese Referenz :
LWert-zu-rWert-, Array-zu-Zeiger- oder Funktions-zu-Zeiger- Konvertierungen werden nicht durchgeführt.
[Betonung meiner]