Prev: Updated performance tests using Boost Serialization lib
Next: Fast Assignment of POD Struct Whose Members Have Copy Constructors
From: zrb on 6 Dec 2009 03:11 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 6 Dec 2009 10:49 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 7 Dec 2009 02:54 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 8 Dec 2009 08:56 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 11 Dec 2009 03:16
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! ] |