Re: do decltype and lambda function mix?
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<class F, class ...Args>
auto call(F f, Args&&...args) ->
decltype(f(std::forward<Args>(args)...))
{
while(1)
{
try { return f(std::forward<Args>(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! ]