Auto comme type de retour

avec séparation du code

a marqué ce sujet comme résolu.

Bonjour à tous.

Je cherche à faire marcher le code suivant :

1
2
// f.h 
auto f();
1
2
3
4
// f.cpp 
auto f(){
return 42;
}
1
2
3
4
5
6
7
// main.cpp 
#include "f.h"
int main(int argc, char *argv[])
{
  int i = f();
  return 0;
}

Le soucis actuel, c'est que dans main.cpp, le compilateur n'a pas vu le corps de f, il est donc incapable d'inférer son type de retour. Si j'utilisef dans f.cpp après sa définition, tout marche bien.

Une idée de comment résoudre ca ? Ou c'est une limitation inhérente au couple langage/mécanisme de compilation ?

Merci. David.

Salut !

Intuitivement je dirai que tu dois rapprocher la définition de la déclaration tant que tu ne précises pas le type, parce que le compilateur n'a absolument aucune information sur le .h, et compiler un .cpp n'apporte pas d'information dans le .h. C'est ce qu'a l'air de dire la doc également.

C'est pour quelle utilisation ?

+0 -0

Techniquement, le compilateur replace le auto de la définition par un template U et va ensuite déduire le type dans une seconde passe1. Donc il semblerait que cela vienne plutôt soit du compilateur, soit de la manière dont tu compiles.

J'ai pas de compilateur sous la main mais tu peux essayer de retourner decltype(auto) à la place, juste pour tester.

EDIT: Depuis la norme, je comprends que cela devrait marcher:

The proposed wording allows non-defining declarations so long as all declarations have the same declared type, without considering the deduced type.

1
2
3
auto f(); // return type is unknown
auto f() { return 42; } // return type is int
auto f(); // redeclaration

+0 -0

Salut !

Intuitivement je dirai que tu dois rapprocher la définition de la déclaration tant que tu ne précises pas le type, parce que le compilateur n'a absolument aucune information sur le .h, et compiler un .cpp n'apporte pas d'information dans le .h. C'est ce qu'a l'air de dire la doc également.

C'est pour quelle utilisation ?

unidan

le problème c'est que derrière on a des erreurs de link… C'est pour éviter de me taper le type de retour d'une fonction (qui renvoie un boost::bind…) dans le cadre de construction de stratégies de ré-écriture en C++ .

KFC : La déduction marche bien dans f.cpp. Le truc, c'est que l'information calculée dans la TU {f.cpp,f.h} ne passe pas à {main.cpp,f.h} vu que c'est pas le même TU.

Le code suivant compile mais casse l'ODR si je dis pas de bêtise (à moins de mettre le tout dans un namespace anonyme). Ca marche mais c'est pas hyper beau

1
2
// dans f.h et f.cpp vide
auto f = [](){return 42;};
+0 -0

J'avais deja essayé de retourner un decltype(auto) plutot que auto comme la doc l'indique mais ça n'abouti pas non plus.

Tu peux toujours déclarer ta fonction inline dans le .h pour l'errreur de link.

En tout cas, c'est bien le fonctionnement avec les templates qui me fait dire que ça ne devrait pas être possible. Partout où tu inclus ton fichier, tu devrais pouvoir définir son type de retour avec seulement les informations dans le texte après traitement des #include.

Lu'!

Je pense que tu es simplement dans un cas qui est exactement un problème de déduction façon template. En fait :

If the return type does not use decltype(auto), the deduction follows the rules of template argument deduction.

c'est exactement comme si tu avais une séparation de ton template entre header et source et on sait que ça ne fait pas bon ménage. Il te faudrait quelque chose d'équivalent à la notion de "template explicit instanciation" non ? (EDIT : quoique non, même pas, vu que tu ne veux pas explicitement poser le type).

En général, decltype(auto) sert à faire du perfect forwarding sur le type de retour ou pour retarder sa déduction en cas de template recursive. Ca n'a pas trop de rapport avec le binz.

Je pense qu'à moins de revoir le langage et que les TU disparaissent, y'a pas de bonne solution vu que l'info ne va pas remonter.

Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte