J'essaie de créer une fonction qui peut être appelée avec une Lambda qui prend 0, 1 ou 2 arguments. Étant donné que j'ai besoin du code pour travailler à la fois sur G ++ 4.5 et VS2010 (qui ne prend pas en charge les modèles variadiques ou les conversions Lambda vers des pointeurs de fonction) La seule idée que j'ai proposée est de choisir la mise en œuvre à appeler en fonction de la monnaie. Ce qui est ci-dessous est mon non-marche devinez comment cela devrait regarder. Y a-t-il un moyen de corriger mon code ou y a-t-il un meilleur moyen de le faire en général?
4 Réponses :
Je pensais que ce qui suit fonctionnerait mais ça ne le fait pas, je le pose pour deux raisons.
code suit: p>
STD :: Fonction sait comment envelopper Lambdas, mais vous i> devez fournir directement la signature <...>. Par exemple: "Modèle
Une fonction Lambda est un type de classe avec un seul appel d'appel de fonctions. Vous pouvez ainsi détecter l'arité de cet opérateur d'appel de la fonction en prenant son adresse et en utilisant la résolution de surcharge pour sélectionner la fonction à appeler:
#include <iostream> template<typename F,typename R> void do_stuff(F& f,R (F::*mf)() const) { (f.*mf)(); } template<typename F,typename R,typename A1> void do_stuff(F& f,R (F::*mf)(A1) const) { (f.*mf)(99); } template<typename F,typename R,typename A1,typename A2> void do_stuff(F& f,R (F::*mf)(A1,A2) const) { (f.*mf)(42,123); } template<typename F> void do_stuff(F f) { do_stuff(f,&F::operator()); } int main() { do_stuff([]{std::cout<<"no args"<<std::endl;}); do_stuff([](int a1){std::cout<<"1 args="<<a1<<std::endl;}); do_stuff([](int a1,int a2){std::cout<<"2 args="<<a1<<","<<a2<<std::endl;}); }
Très cool, mais vous n'avez pas besoin d'appeler la fonction (car il vous suffit de contraindre les types de paramètres) et que vous souhaitez renvoyer le nombre de paramètres de do_stuff code> (qui peut être mieux nommé < Code> ARITY code>).
Avec C ++ 11 et des modèles variadiques, nous pouvons faire mieux maintenant.
De cette façon fonctionne:
template<typename F> auto call(F f) -> decltype(f(1)) { return f(1); } template<typename F> auto call(F f, void * fake = 0) -> decltype(f(2,3)) { return f(2,3); } template<typename F> auto call(F f, void * fake = 0, void * fake2 = 0) -> decltype(f(4,5,6)) { return f(4,5,6); } int main() { auto x1 = call([](int a){ return a*10; }); auto x2 = call([](int a, int b){ return a*b; }); auto x3 = call([](int a, int b, int c){ return a*b*c; }); // x1 == 1*10 // x2 == 2*3 // x3 == 4*5*6 }
Compiler des moyens de compilation d'obtention de l'arité d'une fonction ou d'un objet de fonction, y compris celui d'une Lambda:
Pouvez-vous montrer un exemple de code qui appellerait la fonction Lambda?