112 votes

Quel est l'intérêt du template lambda introduit en C++20 alors que C++14 possède déjà le lambda générique ?

c++14 a introduit des lambdas génériques qui ont permis d'écrire en suivant :

auto func = [](auto a, auto b){
    return a + b;
};
auto Foo = func(2, 5);
auto Bar = func("hello", "world");

Il est très clair que ce lambda générique func fonctionne comme une fonction modèle func fonctionnerait.

Pourquoi le comité C++ a-t-il décidé d'ajouter la syntaxe des modèles pour les lamda génériques ?

134voto

Quentin Points 3904

Les lambdas génériques C++14 sont un moyen très cool de générer un foncteur avec une fonction operator () qui ressemble à ça :

template <class T, class U>
auto operator()(T t, U u) const;

Mais pas comme ça :

template <class T>
auto operator()(T t1, T t2) const; // Same type please

Ni comme ça :

template <class T, std::size_t N>
auto operator()(std::array<T, N> const &) const; // Only `std::array` please

Ni comme ça (bien que ce soit un peu délicat à utiliser) :

template <class T>
auto operator()() const; // No deduction

Les lambdas C++14 conviennent, mais C++20 nous permet de mettre en œuvre ces cas sans problème.

45voto

Antoine Morrier Points 1419

Puisque vous pouvez utiliser des lambdas modélisées en C++20, vous pouvez restreindre vos types d'une manière plus facile qu'une expression SFINAE :

auto lambda = []<typename T>(std::vector<T> t){};

Ce lambda ne fonctionne qu'avec les types vectoriels.

31voto

Hamza.S Points 865

La nouvelle "syntaxe de modèle familier" pour les lambdas introduite en C++20 rend les constructions telles que  for_types  et  for_range  viable et beaucoup plus lisible par rapport aux alternatives C++17.

(source : itération en temps de compilation avec les lambdas C++20 )

Une autre chose intéressante qui peut être faite sur les lambdas génériques C++14 et C++17 est d'appeler directement  operator()  en passant explicitement un paramètre de modèle : C++14 :

auto l = [](auto){ };
l.template operator()<int>(0);

C++20 (voir aussi l'explication de <tparams> sur cppreference ) :

auto l = []<typename T>(){ };
l.template operator()<int>();

L'exemple C++14 ci-dessus est tout à fait inutile : il n'y a aucun moyen de faire référence au type fourni à  operator()  dans le corps de la lambda sans donner un nom à l'argument et en utilisant  decltype . De plus, nous sommes obligés de passer un argument même si nous n'en avons pas besoin.

L'exemple C++20 montre comment T est facilement accessible dans le corps du lambda et qu'un lambda nullaire peut maintenant être modélisé de manière arbitraire. Cela va être très utile pour la mise en œuvre des constructions de compilation mentionnées ci-dessus.

27voto

StoryTeller Points 6139

Le site proposition qui a été accepté dans C++20 comporte une longue section de motivation, avec des exemples. Le principe de base est le suivant :

Il y a quelques raisons principales pour lesquelles la syntaxe actuelle de définition de lambdas génériques est jugée insuffisante par l'auteur. L'essentiel est que que certaines choses qui peuvent être faites facilement avec des modèles de fonctions normaux nécessitent un saut de puce important pour être réalisées avec les lambdas génériques, ou ne peuvent pas être réalisées du tout. L'auteur pense que les lambdas ont suffisamment de valeur pour que le C++ les prenne en charge. L'auteur pense que les lambdas ont suffisamment de valeur pour que le C++ les prenne en charge aussi bien que les modèles de fonctions normaux. fonctions normales.

Il y a ensuite de nombreux exemples.

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