51 votes

Pourquoi ne pouvons-nous pas avoir des types de retour déduits automatiquement?

Récemment, j'ai été travailler à un ami qui voulait faire du C++ plus Haskell-y, et nous voulions une fonction qui est en gros comme ceci:

auto sum(auto a, auto b) {
    return a + b;
}

Apparemment je ne peux pas utiliser l'auto comme un type de paramètre, alors je l'ai changé à cela:

template<class A, class B>
auto sum(A a, B b) {
    return a + b;
}

Mais cela ne fonctionne pas non plus. Ce que nous avons finalement réalisé que nous avons besoin de ceci:

template<class A, class B>
auto sum(A a, B b) -> decltype(a + b) {
    return a + b;
}

Donc ma question est, quel est le point? N'est-ce pas decltype il suffit de répéter l'information, puisque le compilateur peut-il suffit de regarder l'instruction de retour?

J'ai pensé que peut-être c'est nécessaire afin que nous puissions simplement inclure un fichier d'en-tête:

template<class A, class B>
auto sum(A a, B b) -> decltype(a + b);

... mais nous ne pouvons pas utiliser des modèles comme ça de toute façon.

L'autre chose que j'ai considéré est qu'il pourrait être plus facile pour le compilateur, mais il me semble qu'il serait plus difficile.

Cas 1: Avec decltype

  • Déterminer le type de l' decltype déclaration
  • Comprendre les types de toutes les valeurs de retour
  • Voir si elles correspondent

Cas 2: Sans decltype

  • Comprendre les types de toutes les valeurs de retour
  • Voir si elles correspondent

Donc, avec ces choses à l'esprit, ce qui est le point de fuite type de retour avec decltype?

8voto

Nicol Bolas Points 133791

mais nous ne pouvons pas utiliser des modèles comme ça de toute façon.

Tout d'abord, de fuite des types de retour ne sont pas purement un modèle chose. Ils travaillent pour toutes les fonctions. Deuxièmement, selon qui? Ce qui est parfaitement légal code:

template<class A, class B>
auto sum(A a, B b) -> decltype(a + b);

template<class A, class B>
auto sum(A a, B b) -> decltype(a + b)
{
}

La définition du modèle pourrait être dans l'en-tête. Ou peut-être dans un autre fichier, de sorte que vous n'avez pas à parcourir des pages et des pages de définitions de fonction lors de la recherche par le biais d'une interface.

C++ a à rendre compte de toutes les possibilités. La restriction de fuite des types de retour juste à la définition d'une fonction signifie que vous ne pouvez pas faire quelque chose d'aussi simple que cela:

template<class A, class B>
class Foo
{
  auto sum(A a, B b) -> decltype(a + b);
}

template<class A, class B>
auto Foo<A, B>::sum(A a, B b) -> decltype(a + b)
{
}

Et cette situation est assez courante pour de nombreux programmeurs. Il n'y a rien de mal à vouloir le code de cette façon.

La seule raison pour laquelle les lambdas s'en sortir sans le type de retour est parce qu'ils ont d'avoir un corps de fonction définie à la définition. Si vous restreint de fuite des types de retour pour les fonctions où la définition est disponible, vous ne seriez pas en mesure d'utiliser l'un des cas ci-dessus.

5voto

Ayjay Points 1717

Il n'y a pas de raison technique pour laquelle il n'est pas possible. La principale raison qu'ils n'ont pas, c'est parce que le langage C++ se déplace très lentement et il faut un temps très long pour les fonctionnalités à ajouter.

Vous pouvez presque obtenir le bon de syntaxe que vous voulez avec les lambdas (mais vous ne pouvez pas avoir templacised arguments dans les lambdas, encore une fois sans aucune raison valable).

auto foo = [](int a, double b)
{
    return a + b;
};

Oui, il y a certains cas où le type de retour n'a pas pu être automatiquement déduit. Tout comme dans une lambda, il pourrait simplement être une exigence de déclarer le type de retour de vous-même dans ces cas ambigu.

À l'heure actuelle, les restrictions sont tellement arbitraire que d'être assez frustrant. Voir également la suppression de concepts pour l'ajout de la frustration.

0voto

Paul Points 4552

Dans un article de blog de Dave Abrahams, il discute d'une proposition visant à avoir cette syntaxe de fonction:

 []min(x, y)
{ return x < y ? x : y }
 

Ceci est basé sur une proposition possible de lambda polymorphe. Il a également commencé à travailler ici sur la mise à jour de clang pour prendre en charge cette syntaxe.

-1voto

Peng Wang Points 29

Peu d’espoir de persuader le comité d’ajouter un élément linguistique de ce type, même s’il n’ya pas d’obstacles techniques. Mais peut-être est-il possible de persuader le groupe GCC d'ajouter une extension de compilateur.

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