Retourner la déduction de type avec un prototype explicite en C ++

J’ai joué avec la déduction de type de retour prise en charge dans g ++ avec -std = c ++ 1y.
Si vous prototypez une fonction avec un type de retour explicite et tentez ensuite de définir la fonction avec déduction du type de retour, le compilateur se plaint d’une ancienne déclaration ambiguë:

std::ssortingng some_function(); ... auto some_function(){ return std::ssortingng{"FOO"}; } //fails to comstack 

Y a-t-il une bonne raison pour que cela ne fonctionne pas?
Mon raisonnement pour utiliser la déduction de type de retour dans la définition est de garder le code propre, mais je souhaite un type explicite dans le prototype pour des raisons d’auto-documentation. Des recommandations sur les meilleures pratiques pour savoir quand et quand ne pas utiliser la déduction du type de retour seraient appréciées 🙂

Pour être plus clair, je voudrais des réponses à:
1. Est-ce une erreur d’implémentation dans le compilateur? (Je suis à peu près sûr que ce n’est pas le cas)
2. Ce type de déduction peut-il être effectué, mais la proposition ne le permet pas. Si oui, pourquoi pas?
3. Si cela est vraiment ambigu, quels sont quelques exemples où déduire le type et essayer de le faire correspondre à une déclaration forward explicite vous poserait des problèmes?
4. Y a-t-il des problèmes plus spécifiques de mise en œuvre derrière cela?
5. Est-ce simplement un oubli?

Cela tient à la façon dont les tables de fonctions et les fonctions surchargées fonctionnent en C ++.

Lorsque le compilateur lit votre std::ssortingng some_function(); il crée un emplacement pour qu’il soit référencé dans le fichier binary et indique si “cette fonction est appelée” access à cet emplacement “.

Nous avons donc une table qui ressemble à ceci …

 (Address offset) (Symbol) 0x???????? std::ssortingng somefunction(); 

Maintenant, il arrive à votre auto some_function() {...} . Normalement, il faudrait d’abord regarder dans la table des fonctions pour voir si auto somefunction(); existe dans la table ou dans une variante de celle-ci, mais le compilateur remarque qu’il s’agit d’une implémentation et qu’il possède le mot-clé auto; il est donc *blank* some_function(); de réduire l’entropie *blank* some_function(); à la table de fonction et les liens pour résoudre le type de retour.

Maintenant, la table de fonction ressemble à ceci …

 (Address offset) (Symbol) 0x???????? std::ssortingng somefunction(); 0x???????? ????? somefunction(); 

Donc, il comstack le code en binary lorsqu’il découvre le type de retour qui, dans ce cas, est std::ssortingng . Le compilateur sait maintenant quel est le type de retour, il passe donc à la table des fonctions et modifie auto somefunction(); trop std::ssortingng somefunction(); .

Maintenant, la table de fonction ressemble à ceci …

 (Address offset) (Symbol) 0x???????? std::ssortingng somefunction(); 0x???????? std::ssortingng somefunction(); 

Maintenant, le compilateur retourne et continue à comstackr la fonction. Une fois que c’est fait, il retourne et termine la table vtable seulement pour trouver le même symbole est là deux fois. Il est maintenant ambigu de savoir à quel symbole nous nous référons également.

Alors, quelle est la raison de cela?

Ce n’est pas sûr à 100%, mais les vtables sont créées bien avant que votre code soit suffisamment réduit pour permettre le type de déduction. Ainsi, la seule option avec laquelle le compilateur doit travailler à ce stade est simplement de supposer que c’est un nouveau symbole. C’est juste quelque chose que j’ai remarqué en regardant des tables de symboles toute la journée et en écrivant mon propre compilateur C ++ 11.

Cependant, je ne peux en aucune façon parler au nom d’autres compilateurs où de nombreuses optimisations et autres étapes ont été introduites. Je travaille simplement avec les principes de base, mais c’est ma compréhension de la norme.

Une dernière chose que le type est complètement arbitraire. Peu importe qu’ils ne correspondent pas au moment de la déduction. Cela ne va jamais aussi loin. Le problème se pose qu’il y a deux symboles identiques dans la table et que vous ne pouvez pas surcharger les types de retour.

vous devez le faire comme:

 auto some_function() -> decltype(std::ssortingng) { return std::ssortingng{"FOO"}; } 

pour plus d’informations, consultez http://en.wikipedia.org/wiki/C%2B%2B11 -> syntaxe de fonction alternative