32 votes

Différence de type entre "fun" et "&fun" ?

Faites des expressions fun y &fun ont le même type ou pas ?

Considérons le code suivant :

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;

Les deux assertions réussissent, ce qui suggère que les deux expressions ont le même type. Cependant, typeid donnent des résultats différents :

FvvE
PFvvE

Pourquoi ça ?

30voto

VTT Points 27056

Les deux assertions réussissent car elles sont appliquées au type T déduit de l'argument de la fonction. Dans les deux cas, il sera déduit qu'il s'agit d'un pointeur vers une fonction, car les fonctions se décomposent en un pointeur vers une fonction. Cependant, si vous réécrivez les assertions pour accepter les types directement, la première échouera :

static_assert(is_same<void(*)(), decltype(fun)>::value);
static_assert(is_same<void(*)(), decltype(&fun)>::value);

compilateur en ligne

18voto

songyuanyao Points 2265

fun y &fun se réfèrent au même type en raison de conversion de la fonction en pointeur qui se déroule en check<void(*)()>(fun); mais typeid est une exception.

(c'est moi qui souligne)

Lvalue-to-rvalue, array-to-pointer, ou les conversions de fonction à pointeur ne sont pas effectuées .

Et pourquoi la conversion de la fonction en pointeur est effectuée pour check<void(*)()>(fun); car dans déduction d'un argument modèle ,

Avant que la déduction ne commence, les ajustements suivants à P y A sont réalisées :

1) Si P n'est pas un type de référence,

  • si A est un type de tableau, ... ;
  • sinon, si A est un type de fonction, A est remplacé par le type de pointeur obtenu par la conversion fonction-pointeur ;

check() prend le paramètre par valeur, alors la conversion de fonction à pointeur est effectuée et le type déduit de T sera également le pointeur de la fonction, c'est-à-dire que void(*)() .

7voto

Joachim Pileborg Points 121221

Lorsque vous utilisez le nom d'une fonction comme expression, elle se désintègre vers un pointeur sur lui-même. Ainsi, fun sera le même que &fun .

Quant à la typeid chose, de cette référence :

Lvalue-to-rvalue, array-to-pointer, ou fonction-à-pointeur les conversions ne sont pas effectuées.

(C'est moi qui souligne)

0 votes

Pourquoi est-ce que typeid renvoient des noms de types différents ?

0 votes

@NPS Parce que function-to-pointer conversions are not performed.

0 votes

[conv.func]/1 le dit puede ("Une lvalue de type fonction T peut être convertie en une prvalue de type "pointeur vers T". Le résultat est un pointeur vers la fonction."), mais je ne trouve pas de règle le disant fait .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X