From: zrb on
I have started playing around with GCC 4.5 and having trouble getting
this to work...

class LambdaMember
{
public:
LambdaMember(int x) : m_x(x)
{
}

private:
int m_x;

public:
auto getterX() -> decltype([this]() -> int {return this->m_x;})
{
return [this]() -> int {return this->m_x;};
}
};

How do I declare getterX() function? It returns a lambda that uses
"this", but how do I specify its return type?

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: SG on
On 6 Dez., 21:11, zrb <zraj...(a)gmail.com> wrote:
> I have started playing around with GCC 4.5 and having trouble
> getting this to work...
>
> class LambdaMember
> {
> public:
> LambdaMember(int x) : m_x(x)
> {
> }
> private:
> int m_x;
> public:
> auto getterX() -> decltype([this]() -> int {return this->m_x;})
> {
> return [this]() -> int {return this->m_x;};
> }
> };
>
> How do I declare getterX() function? It returns a lambda that uses
> "this", but how do I specify its return type?

You don't. As far as I can tell it's not possible to let a "normal"
function return a lambda directly. I see two (potential) problems
here:

1. Every lambda expression has its own unique but anonymous type.
So, in

auto foo = [](int x){return x+1;};
auto bar = [](int x){return x+1;};

the type of foo is not the same as the type of bar (from what I
can tell -- correct me if I'm wrong).

2. The operand of decltype is an unevaluated context. Therefore, it
can appear outside of function bodies like in your example. But
outside of a function's body some variables you want to include
in the capture clause might not be in scope yet. I'm not sure if
that applies to the keyword 'this' in your example.

This explains, why it is ILLEGAL to use a lambda expression as operand
to alignof, decltype and sizeof. Think about it. decltype would return
some type that is "incompatible" with the second lambda expression's
type.

What about lambdas returning lambdas? :-)

auto foo = []{return [](int x){return x+1};};
auto bar = foo();
int x = bar(42);

I think it's legal. At least I don't see why it shouldn't work since
decltype isn't used here. So, in case we get return type inference for
"normal inline functions" as well (see "unified function proposal")
you would be able to write

...
public:
[]getterX()
{
return [this]() -> int {return this->m_x;};
}
};

....not that I would really write code like this.

Cheers,
SG


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: gpderetta on
On Dec 6, 8:11 pm, zrb <zraj...(a)gmail.com> wrote:
> I have started playing around with GCC 4.5 and having trouble getting
> this to work...
>
> class LambdaMember
> {
> public:
> LambdaMember(int x) : m_x(x)
> {
> }
>
> private:
> int m_x;
>
> public:
> auto getterX() -> decltype([this]() -> int {return this->m_x;})
> {
> return [this]() -> int {return this->m_x;};
> }
>
> };
>
> How do I declare getterX() function? It returns a lambda that uses
> "this", but how do I specify its return type?
>

I haven't really played yet with lambdas, but std::function should
work:

std::function<int()>
getterX() {
return [this]() -> int {return this->m_x;};
}

Note that std::function is usually optimized not to dinamically
allocate when containing small functors, like in this case (only
'this' is being bound).

HTH,

--
Giovanni P. Deretta


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Klaus Rudolph on
zrb schrieb:
> I have started playing around with GCC 4.5 and having trouble getting
> this to work...
>
> class LambdaMember
> {
> public:
> LambdaMember(int x) : m_x(x)
> {
> }
>
> private:
> int m_x;
>
> public:
> auto getterX() -> decltype([this]() -> int {return this->m_x;})
> {
> return [this]() -> int {return this->m_x;};
> }
> };
>
> How do I declare getterX() function? It returns a lambda that uses
> "this", but how do I specify its return type?
>


It is only possible to return a lambda containing object which is a
template class as I know.

My idea while reading about lambdas was to use them as functors. But
there is no way to declare the correct type. The "trick" now is to use a
template which is able to hold an lambda function an call maybe the
operator() for execution of the lambda function. I have no idea why we
have to do it in such a difficult way. Why not directly describe the
lambda type?

My usage of lambda generating functions is as follows:

class BaseFunc
{
public:
virtual int Do(int)=0;
};

template <class F>
class Functor : public BaseFunc
{
private:
F lambdaPtr;

public:
Functor (F _ptr):lambdaPtr(_ptr) {}
int Do(int a) {return lambdaPtr(a); }
};

template <class F>
BaseFunc* Generate(F func)
{
BaseFunc* a1=new Funktor<F>(func);
return a1;
};

//and now use it:
BaseFunc* SubGenerate()
{
int local=90;
return Generate([=local] (int in)->int { cout << "The function
itself" << endl; return local * in * 123;} );
}

//






--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Frank Birbacher on
Hi!

SG schrieb:
> 1. Every lambda expression has its own unique but anonymous type.
> So, in
>
> auto foo = [](int x){return x+1;};
> auto bar = [](int x){return x+1;};
>
> the type of foo is not the same as the type of bar (from what I
> can tell -- correct me if I'm wrong).

Is it possible to have member variables declared with automatic type
discovery? Like

struct TestLambda
{
int x;
auto const getX = [](){ return x; };
decltype(getX) getterX() { return getX; }
};

I don't have any clue about how these new features work. Maybe I cannot
have the initialiser in the class definition. And if I cannot then
"auto" will not be able to infer a type. So, how does it work?

Frank

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]