From: SG on
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
> 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
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
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! ]