12
votes

Est un trait C ++ is_lambda, purement mis en œuvre comme une bibliothèque, impossible?

J'ai une question concernant C ++ 0x Lambdas. Dans mon code, il serait avantageux de savoir si un type donné ou non est le type d'expression de Lambda C ++ 0x. Pour donner un exemple:

typedef decltype(&T::operator()) call_type;


3 commentaires

Je me demande ce que l'utiliseriez-vous?


Désolé pour la réponse tardive. Oui, je pense avoir fait une erreur logique. Il ne sert à rien de distinguer les foncteurs réguliers de Lambdas - je peux voir ce dernier comme le premier. Cependant, il est nécessaire de déterminer si un appel téléphonique existe ou non. À cette date, aucune solution entièrement générique pour ce problème ne semble exister. Je vais aborder cela dans une question distincte bientôt, avec mes tentatives.


@MAXIMYEGORUSKINKIN: quant à une différence de motivation: le type d'un objet fermeture identifie de manière unique la mise en œuvre de la mise en œuvre. La même chose n'est pas (nécessairement) vraie pour d'autres pointeurs de fonction ou autre fonction comme des objets.


4 Réponses :


6
votes

Je ne crois pas que cela puisse être fait - Lambdas n'est pas vraiment quelque chose de nouveau sémantiquement, ce ne sont que des foncteurs générés par le compilateur et seront donc identiques aux foncteurs ordinaires.


0 commentaires

8
votes

Étant donné que l'évaluation de Lambda entraîne une création d'un objet de fermeture, il n'y a aucune différence dès que l'objet est passé à une fonction ou copiée. Et franchement, je ne peux pas imaginer un problème qui nécessiterait de savoir si un objet est venu de Lambda.

éditer. Une norme a même une note en 5.1.2 / 2:

Remarque: un objet de fermeture se comporte comme un objet de fonction (20.8) .- Note de fin


1 commentaires

J'imagine que vous pouviez être prêt à savoir si un std :: fonction <...> est soteleux ou non. Cependant, étant donné que les fonctions sont autorisées à utiliser statique ou de variables globales, leur ne serait pas beaucoup de point dans la distinction de Lambdas du mélange.



2
votes

Il est possible de définir du code de macro qui détermine si une expression est une expression em> lambda (mais ce n'est pas très utile car il ne vous dit pas si une expression est d'un type d'expression de Lambda em>).

#include <type_traits>

template<typename T, typename U>
struct SameType {
    static_assert(!std::is_same<T, U>::value, "Must use Lambda");
    static T pass(T t) { return t; }
};

template <typename T, typename U>
T NotLambda(T t, U u) { return SameType<T, U>::pass(t); }

#define ASSERT_LAMBDA(x) NotLambda(x,x)

/////////////////////////////////////

int fn() { return 0; }

int main() {
    auto l = []{ return 0; };
    return ASSERT_LAMBDA(fn)() +             // << fails
           ASSERT_LAMBDA(l)() +              // << fails
           ASSERT_LAMBDA([]{ return 0; })(); // << passes
}


1 commentaires

J'ai eu la même idée. Si seulement cela pouvait être fait sans la macro laide, mais alors que je trouve la syntaxe d'utiliser NotLambda directement (avec une expression Lambda deux fois), à tolérer, un utilisateur pourrait bien sûr fournir accidentellement deux fonctions distinctes. objets.



1
votes

J'ai créé un compilateur d'en-tête spécifique (MSVC> = 19.20?, GCC> = 7,3, clang> = 6.0) is_lambda Type Trait dans C ++ 17 Si quelqu'un vous intéresse.

https://github.com/schamb/is_lambda-cpp-type-Traïlle

Ceci peut être utilisé comme dans la question suivante: xxx

Il y a plus Exemples pour l'utilisation.



1 commentaires

TL; DR: L'idée est d'utiliser < Code> __ jolie_function __ astuce Pour déterminer le nom du type et vérifier si vous ressemble à "lambda à foo.cpp" .