À partir de C++14, il y a une différence.
C++14 ajoute un cas particulier où les parenthèses autour d'une valeur de retour peuvent altérer la sémantique. Cet extrait de code montre deux fonctions étant déclarées. La seule différence réside dans les parenthèses autour de la valeur de retour.
int var1 = 42;
decltype(auto) func1() { return var1; } // le type de retour est int, identique à decltype(var1)
decltype(auto) func1() { return(var1); } // le type de retour est int&, identique à decltype((var1))
Dans le premier func1
retourne un int
et dans le second func1
retourne un int&
. La différence de sémantique est directement liée aux parenthèses environnantes.
Le spécificateur auto
sous sa forme la plus récente a été introduit en C++11. Dans le specification du langage C++, il est décrit comme suit :
Spécifie que le type de la variable qui est déclarée sera automatiquement déduit de son initialisateur. Pour les fonctions, spécifie que le type de retour est un type de retour en suffixe ou sera déduit à partir de ses instructions de retour (depuis C++14)
Ainsi, C++11 a introduit le spécificateur decltype
qui est décrit dans la specification du langage C++ :
Inspecte le type déclaré d'une entité ou interroge le type de retour d'une expression.
[snip]
-
Si l'argument est soit le nom non parenthésé d'un objet/fonction, ou est une expression d'accès à un membre (objet.membre ou pointeur->membre), alors le decltype spécifie le type déclaré de l'entité spécifiée par cette expression.
-
Si l'argument est toute autre expression de type T, alors
a) si la catégorie de valeur de l'expression est xvalue, alors le decltype spécifie T&&
b) si la catégorie de valeur de l'expression est lvalue, alors le decltype spécifie T&
c) sinon, decltype spécifie T
[snip]
Notez que si le nom d'un objet est parenthésé, il devient une expression lvalue, donc decltype(arg) et decltype((arg)) sont souvent des types différents.
En C++14, la capacité d'utiliser decltype(auto)
a été autorisée pour les types de retour des fonctions. Les exemples originaux sont là où la différence sémantique avec les parenthèses entre en jeu. Revisitant les exemples originaux :
int var1 = 42;
decltype(auto) func1() { return var1; } // le type de retour est int, identique à decltype(var1)
decltype(auto) func1() { return(var1); } // le type de retour est int&, identique à decltype((var1))
decltype(auto)
permet au type de retour en fin de fonction d'être déduit de l'entité/expression sur l'instruction de retour. Dans la première version return var1;
est effectivement identique à retourner le type decltype(var1)
(un type de retour int
selon la règle 1 ci-dessus) et dans le deuxième cas return (var1);
c'est effectivement identique à decltype((var1))
(un type de retour int &
selon la règle 2b).
Les parenthèses font que le type de retour est int&
au lieu de int
, donc un changement de sémantique. Morale de l'histoire - "Toutes les parenthèses dans un type de retour ne sont pas équivalentes"
0 votes
Merci Rob, tu as capturé avec succès l'esprit de la question. En Essence je me demandais si le compilateur faisait quelque chose de spécial (comme essayer d'évaluer l'expression d'abord) ou s'il l'ignorait simplement.
1 votes
Il est difficile de répondre à cette question pour tout
c++
/c
. Ce serait bien d'être plus précis sur la définition du langage, mais je ne sais pas comment corriger cela 9 ans plus tard.0 votes
Pour
C
il y a un doublon stackoverflow.com/questions/161879/…