Prev: template<unsigned char local_size, typename wide_type> struct fast_string{...};
Next: Static Member Function - Function Pointer
From: Helmut Jarausch on 14 Apr 2010 03:19 Hi, how can I declare a function which takes a lambda-expression. Naively, I tried // compile with gcc-4.5 -std=c++0x #include <iostream> using std::cout; using std::cerr; using std::cin; using std::endl; void calc(double x, double CVT(double)) { cout << "\nresult= " << CVT(x) << endl; } int main() { double F; cerr << "F= "; cin >> F; calc(3.14,[&](double z) -> double { return F*z; } ); } But it fails, since it cannot convert the lambda-expression to a double (*)(double). What is the correct declaration of the function 'calc'. Many thanks for a hint and pointers to tutorials on that subject. Sorry, but I couldn't extract that information out of the N2550 document. Helmut. -- Helmut Jarausch Lehrstuhl fuer Numerische Mathematik RWTH - Aachen University D 52056 Aachen, Germany [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Daniel Krügler on 14 Apr 2010 07:58 On 14 Apr., 20:19, Helmut Jarausch <jarau...(a)igpm.rwth-aachen.de> wrote: > how can I declare a function which takes a lambda-expression. > Naively, I tried > > // compile with gcc-4.5 -std=c++0x > > #include <iostream> > using std::cout; using std::cerr; using std::cin; using std::endl; > > void calc(double x, double CVT(double)) { > cout << "\nresult= " << CVT(x) << endl; > > } > > int main() { > double F; > cerr << "F= "; cin >> F; > > calc(3.14,[&](double z) -> double { return F*z; } ); > } > > But it fails, since it cannot convert the lambda-expression to > a double (*)(double). > > What is the correct declaration of the function 'calc'. > > Many thanks for a hint and pointers to tutorials on that subject. > Sorry, but I couldn't extract that information out of the N2550 document. The most recent working draft is N3090 (which has the same content as the recently passed FCD). Regarding your particular use-case there does not exist a non-template solution. The current wording says that any lambda closure with *no* lambda-capture has a publicly available conversion function to pointer to function that has the same return type and parameter types as the lambda closure. In your example you use a non-empty capture (and you need that), so you would need to provide a template function that uses the function call operator of the closure. HTH & Greetings from Bremen, Daniel Kr�gler -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Mathias Gaunard on 14 Apr 2010 07:59 On 14 avr, 19:19, Helmut Jarausch <jarau...(a)igpm.rwth-aachen.de> wrote: > Hi, > > how can I declare a function which takes a lambda-expression. > Naively, I tried > > // compile with gcc-4.5 -std=c++0x > > #include <iostream> > using std::cout; using std::cerr; using std::cin; using std::endl; > > void calc(double x, double CVT(double)) { > cout << "\nresult= " << CVT(x) << endl; > > } > [...] > What is the correct declaration of the function 'calc'. template<typename F> void calc(double x, F&& CVT) { cout << "\nresult= " << CVT(x) << endl; } Alternatively you can use std::function or std::nested_function. -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Juan Pedro Bolivar Puente on 14 Apr 2010 07:59 On 14/04/10 21:19, Helmut Jarausch wrote: > Hi, > > how can I declare a function which takes a lambda-expression. > Naively, I tried > > [...] > > What is the correct declaration of the function 'calc'. > Every lambda expression has its own type which is known only by the compiler. To store the lambda expression in a local variable you can use 'auto' to infer its type, but to pass it to another function you can: a) Make that function a template so the compiler can instantiate it with the exact inferred type of the lambda. This is: template <typename Func> void calc (double x, Func cvt); b) Use std::function for type erasure, this is: void calc (double x, std::function <double (double)> cvt); The (a) case is more efficient because the function is instantiated for the exact type of the lambda and potentially use the stack to store the closure while (b) would potentially store the closure in the heap and add a extra level of indirection. On the other hand, (a) has all the limitations of templated functions: cannot be overriden in sub-classes, their implementation have to be exposed in header files, etc, while option (b) does not. JP -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Hakusa on 14 Apr 2010 08:00
On Apr 14, 2:19 pm, Helmut Jarausch <jarau...(a)igpm.rwth-aachen.de> wrote: > Hi, > > how can I declare a function which takes a lambda-expression. > Naively, I tried > void calc(double x, double CVT(double)) { > cout << "\nresult= " << CVT(x) << endl; > > } > int main() { > double F; > cerr << "F= "; cin >> F; > > calc(3.14,[&](double z) -> double { return F*z; } ); > > } > > But it fails, since it cannot convert the lambda-expression to > a double (*)(double). > > What is the correct declaration of the function 'calc'. Making calc work only for lambdas might be difficult, they have no standard-defined type. But, i don't think you want to make it so calc will take ONLY lambdas anyway, since the usability of it will be limited, especially to people NOT using -std=c++0x when they compile. template< typename F > void calc( double x, F f ) { cout << "\nresult= " << f(x) << endl; } Here, the argument f can be a function pointer, a function object, or a lambda. As long as type F fulfills to requirement of having operator()(double), this will work. You can also use std::tr1::function which has a typedef for result_type. -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |