Prev: template<unsigned char local_size, typename wide_type> struct fast_string{...};
Next: Static Member Function - Function Pointer
From: SG on 14 Apr 2010 08:34 On 14 Apr., 20:19, Helmut Jarausch 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). The C++ standard will allow conversions to function pointers but not in cases like these. Remember that the lambda syntax does two things: It defines a new nameless type and creates an object of this type. In its operator() member function you access something called F. You could think of F as a reference member of that class. With this im mind it should be obvious why there cannot be a conversion to a function pointer. Your pointer CVT is a pointer to a free function which doesn't have any kind of data or reference to data (like F) attached to it. > What is the correct declaration of the function 'calc'. You have basically two options. 1.: template<class Fun> void calc(double x, Fun fun) { cout << "\nresult= " << fun(x) << endl; } 2.: #include <function> void calc(double x, std::function<double(double)> fun) { cout << "\nresult= " << fun(x) << endl; } Cheers, SG -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Thiago A. on 14 Apr 2010 08:37 > how can I declare a function which takes a lambda-expression. > Naively, I tried I think you have two options: 1) Use template argument T 2) Use std::function argument -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Magnus Müller on 14 Apr 2010 08:41 Hi, ::But it fails, since it cannot convert the lambda-expression to ::a double (*)(double). I suspect that you received the following warning (or similar): lambdaold.cpp:31:53: error: cannot convert 'main()::<lambda(double)>' to 'double (*)(double)' for argument '2' to 'void calc(double, double (*)(double))' ::What is the correct declaration of the function 'calc'. I think the warning is related to the fact, that the lambda function uses variables local to the function main (). The following compiles here (gcc version 4.5.0 20100404 (experimental) [trunk revision 157958] (Debian 4.5-20100404-1)) without a warning: #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 a = 10; int main() { calc (2.71, [&](double z) -> double { return a*z; }); } Whereas it failes with the upper error message using int main() { int a = 10; calc (2.71, [&](double z) -> double { return a*z; }); } I don't know if the error your source reproduces should be considered as a bug, what does the c++0x say about lambda expressions which use local variables? Greetings, Magnus -- [ 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 15:53
On 15 Apr., 01:41, Magnus M�ller <mamue...(a)informatik.hu-berlin.de> wrote: > Hi, > > ::But it fails, since it cannot convert the lambda-expression to > ::a double (*)(double). > > I suspect that you received the following warning (or similar): > lambdaold.cpp:31:53: error: cannot convert �main()::<lambda(double)>� to �double (*)(double)� for argument �2� to �void calc(double, double (*)(double))� > Well, this looks like a funny description of a "warning" ;-) > ::What is the correct declaration of the function 'calc'. > > I think the warning is related to the fact, that the lambda function uses variables local to the function main (). The following compiles here (gcc version 4.5.0 20100404 (experimental) [trunk revision 157958] (Debian 4.5-20100404-1)) without a warning: > > #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 a = 10; > int main() { > calc (2.71, [&](double z) -> double { return a*z; }); > } If this is well-formed, the compiler provides an extension. Per current working draft there should be no conversion function for lambda closures with a lambda-capture. In your example exists a lambda- capture, even though there is no captured variable. But the term lambda-capture is defined per grammar and the code uses this grammar, therefore this code should be ill-formed. > Whereas it failes with the upper error message using > > int main() { > int a = 10; > calc (2.71, [&](double z) -> double { return a*z; }); > > } > > I don't know if the error your source reproduces should be considered as a bug, what does the c++0x say about lambda expressions which use local variables? > The current working draft refers to the existence or absence of lambda-capture. This is the "[&]" in above example and can take different forms. If no lambda-capture exists, there is the guarantee that no local variables are "captured". This is necessary to allow for a conversion function to a pointer to a function, because this pointer must point to some function that can be defined without state. 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! ] |