home bbs files messages ]

Forums before death by AOL, social media and spammers... "We can't have nice things"

   comp.lang.c++.moderated      Moderated discussion of C++ superhackery      33,346 messages   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]

   Message 32,167 of 33,346   
   =?ISO-8859-1?Q?Daniel_Kr=FCgler?= to All   
   Re: do decltype and lambda function mix?   
   21 Apr 12 13:21:13   
   
   68cf3209   
   From: daniel.kruegler@googlemail.com   
      
   Am 21.04.2012 03:46, schrieb Gene Bushuyev:   
   > I reduced our current code to this simple snippet:   
   >   
   > struct except : public std::exception   
   > {   
   >     virtual const char* what() const throw() { return "except"; }   
   > };   
   >   
   > void grow() { static unsigned n = 0; if(n++<  2) throw   
   > std::bad_alloc(); }   
   >   
   > template   
   > auto call(F f, Args&&...args) ->   
   > decltype(f(std::forward(args)...))   
   > {   
   >       while(1)   
   >       {   
   >           try { return f(std::forward(args)...); }   
   >           catch(except&  e) { grow(); }   
   >       }   
   > }   
   >   
   > int main()   
   > {   
   >     call([]{});   
   >     return call([](int s) { std::cerr<<  s; return s; }, 123);   
   > }   
   >   
      
   [..]   
      
   > The function object in this case is lambda function. The question is   
   > whether this code standard compliant?   
      
   Ignoring the missing header includes: Yes.   
      
   > The standard forbids lambda   
   > expression in unevaluated context. Does it mean decltype here is   
   > illformed?   
      
   No, the code is fine, because it does not violate this rule: There is   
   no *lambda expression* occurring within an unevaluated context. To   
   create something like this you need to write code along the lines of   
      
   decltype([]{})   
      
   or   
      
   sizeof([]{})   
      
   Your code does only use lambda-expressions in potentially evaluated   
   expressions, like   
      
   call([]{})   
      
   or   
      
   call([](int s) { std::cerr<<  s; return s; }, 123)   
      
   within main. The lambda expression has just some class type and   
   template deduction will have the effect that F is deduced to some   
   class type that was generated by the compiler. There are no such   
   constraints upon these class types *produced* by lambda expressions to   
   occur in unevaluated contexts or else.   
      
   > This code works as expected in gcc 4.6.2, but when attempted to be   
   > ported to 4.7.0, compiler died with segmentation fault, and no error   
   > message.   
      
   This must be some compiler defect in gcc 4.7.0. Your code is accepted   
   by recent gcc 4.8.0 and this is clearly intended to work by the   
   language.   
      
   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! ]   
      
   --- SoupGate-Win32 v1.05   
    * Origin: you cannot sedate... all the things you hate (1:229/2)   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]


(c) 1994,  bbs@darkrealms.ca