webentwicklung-frage-antwort-db.com.de

Unterschied der Art zwischen "Spaß" und "& Spaß"?

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. typeids gibt jedoch unterschiedliche Ergebnisse zurück:

FvvE
PFvvE

Warum das?

30
NPS

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);

Online-Compiler

28
VTT

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(*)().

17
songyuanyao

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]