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)   
|