Comment puis-je stocker une expression lambda comme un champ d'une classe en C++11?
Je voudrais créer une classe où le client peut stocker une expression lambda comme []() -> void {}
comme un champ de la classe, mais je ne peux pas comprendre comment le faire. Une réponse a suggéré d'utiliser decltype
, que j'ai essayé, sans succès. Voici une ideone lien source. Ci-dessous est la source et le résultat:
#include <cstdio>
auto voidLambda = []()->void{};
class MyClass {
public:
decltype(voidLambda) t;
MyClass(decltype(voidLambda) t) {
this->t = t;
}
};
int main() {
MyClass([] {
printf("hi");
});
}
Résultat:
prog.cpp: In constructor 'MyClass::MyClass(<lambda()>)':
prog.cpp:3:79: error: no matching function for call to '<lambda()>::__lambda0()'
prog.cpp:2:20: note: candidates are: <lambda()>::<lambda>(const<lambda()>&)
prog.cpp:2:20: note: <lambda()>::<lambda>(<lambda()>&&)
prog.cpp:3:88: error: no match for 'operator=' in '((MyClass*)this)->MyClass::t = t'
prog.cpp: In function 'int main()':
prog.cpp:5:27: error: no matching function for call to 'MyClass::MyClass(main()::<lambda()>)'
prog.cpp:3:48: note: candidates are: MyClass::MyClass(<lambda()>)
prog.cpp:3:14: note: MyClass::MyClass(const MyClass&)
Personne ne sait comment faire cela?
- Chaque expression lambda crée son propre type unique. Dans
auto A = [](){}; auto B = [](){};
A
etB
ne sont pas du même type. - Malheureusement
struct A { auto x = 0; };
n'est pas autorisé.
Vous devez vous connecter pour publier un commentaire.
Si vous souhaitez qu'un membre de la classe à être une expression lambda, pensez à utiliser le
std::function<>
wrapper type (à partir de la<functional>
en-tête), qui peut contenir n'importe quelle fonction appelable. Par exemple:De cette façon, vous n'avez pas besoin de connaître le type de l'expression lambda. Vous pouvez stocker tout un
std::function<>
de la fonction appropriée le type et le modèle du système prendra en charge tous les types pour vous. Plus généralement, toute appelable entité de la signature peut être attribué à unstd::function<>
, même si le type réel de ce foncteur est anonyme (dans le cas de lambda) ou vraiment compliqué.Le type à l'intérieur de la
std::function
modèle doit être le type de fonction correspondant à la fonction que vous souhaitez stocker. Ainsi, par exemple, pour stocker une fonction qui prend en deuxint
s et renvoie void, tu ferais unstd::function<void (int, int)>
. Pour une fonction qui ne prend aucun paramètre et renvoie unint
, vous pouvez utiliserstd::function<int()>
. Dans votre cas, puisque vous voulez une fonction qui ne prend aucun paramètre et renvoievoid
, vous voulez quelque chose comme ceci:Espérons que cette aide!
-> void
vraiment nécessaire ici ? Je sais que la clause de retour peuvent être omis (et donc déduite) dans un certain nombre de circonstances et ce qui me frappe comme commencer un cas simple (pas dereturn
).return
, le type de retour seront déduits. Sinon, le type de retour est toujoursvoid
. Par conséquent, la-> void
peut être omis.()
car il n'y a pas de paramètres.La seule façon que je peux penser à un magasin lambda dans une classe est d'utiliser un modèle avec une aide
make_
fonction:make_myclass
. C'est le Objet générateur de langage.