75 votes

Le type de retour d'un lambda peut être déduit de la valeur de retour, alors pourquoi pas celui d'une fonction ?

#include <iostream>

int main(){

    auto lambda = [] {
        return 7;
    };

    std::cout << lambda() << '\n';

}

Ce programme compile et imprime 7.
Le type de retour de la lambda est déduit au type entier sur la base de la valeur de retour de 7.


Pourquoi cela n'est-il pas possible avec les fonctions ordinaires ?

#include <iostream>

auto function(){
    return 42;
}

int main(){

    std::cout << function() << '\n';
}

erreur : la fonction 'function' utilise le spécificateur de type 'auto' sans le type de retour qui suit.

77voto

Mark Garcia Points 9851

C++14 aura cette fonctionnalité . Vous pouvez le tester avec de nouvelles versions de GCC ou de clang en définissant l'option -std=c++1y drapeau.

Exemple concret

En plus de cela, en C++14, vous pouvez également utiliser decltype(auto) (qui reflète decltype(auto) comme celle des variables) pour que votre fonction déduise sa valeur de retour en utilisant decltype sémantique.

Un exemple serait celui des fonctions d'acheminement, pour lequel decltype(auto) est particulièrement utile :

template<typename function_type, typename... arg_types>
decltype(auto) do_nothing_but_forward(function_type func, arg_types&&... args) {
    return func(std::forward<arg_types>(args)...);
}

Grâce à l'utilisation de decltype(auto) vous imitez le type de retour actuel de la fonction func lorsqu'il est appelé avec les arguments spécifiés. Il n'y a plus de duplication de code dans le type de retour arrière, ce qui est très frustrant et source d'erreurs en C++11.

25voto

Il s'agit simplement d'une limitation de la façon dont la langue a été créée et a évolué. Dans la future norme C++14, le type de retour d'une fonction peut être déduit dans certains contextes, mais pas dans tous. Il y a des complications lorsqu'il y a plusieurs déclarations de retour.

En outre, les types de retour déduits posent d'autres problèmes, par exemple, le type de retour d'une fonction modèle ne peut pas être utilisé dans une fonction de type SFINAE car pour pouvoir déduire le type, le compilateur doit instancier le gabarit de la fonction, ce qui se produit après substitution. Le résultat net est que, même si cette fonctionnalité sera disponible dans un avenir proche, je l'éviterais si vous pouvez fournir le type vous-même.

10voto

jshrake Points 1661

Cela se passe en c++14. Voir ce qui suit proposition .

6voto

Hitesh Vaghani Points 762

Il n'est pas encore là il sera dans C++1y/C++14 regardez ceci lien de la fonction

5voto

Mehrdad Points 70493

A mon avis, c'est probablement parce que les lambdas inférées par le type ne peuvent pas être récursives .

Pourquoi cela est-il important ? Parce que si un lambda inféré par le type pouvait être récursif (par "inféré par le type", je veux dire lorsque le nom de la variable est de type auto ), alors son type de retour pourrait potentiellement dépendre de lui-même - et bien que cela soit parfois possible à résoudre, c'est beaucoup plus difficile à mettre en œuvre que la "simple" inférence de type. Je ne suis même pas sûr que ce soit toujours solvable (est-elle décidable dans le cas général ?). Si les fonctions supportaient l'inférence de type, ce problème devrait être résolu, il est donc probable qu'ils les aient simplement exclues pour cette raison.

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