Re: Can closure types include type members?
Am 03.12.2011 07:38, schrieb Cassio Neri:
I've been reading bits and pieces of N3242 (which, I suppose is the
latest freely available draft of C++11) and have a question about
lambda expressions or, more precisely, about the closure types.
In [expr.prim.lambda], ?5.1.2/3 it says:
"... An implementation may define the closure type differently from
what is described below provided this does not alter the observable
behavior of the program other than by changing:
? the size and/or alignment of the closure type,
? whether the closure type is trivially copyable (Clause 9),
? whether the closure type is a standard-layout class (Clause 9), or
? whether the closure type is a POD class (Clause 9).
An implementation shall not add members of rvalue reference type to
the closure type."
Since a compiler _may_ alter the size of the closure type and it's
explicitly stated that it "shall not add members of rvalue reference
type", I deduce that a compiler can add members to the closure type
that are not intent to hold copies/references of captures.
Yes, it can, unless that could affect program behaviour in any
observable way (except as mentioned in above quote). But it can only do
so via some compiler-magic, e.g. by using names that are impossible to
create for a programmer (e.g. containing the @ character).
In
particular (and that's what I'm interested in), a compiler may add
type members. Am I right? (I didn't find anything that forbids it.)
Here starts the hard part...
If so, then it would be legal for a compiler to add result_type and
also -- depending on the number of arguments of the closure type's
operator() -- argument_type, first_argument_type and
second_argument_type. By doing so, then the closure type would be
adaptable by STL adaptors.
A compiler could not just add type names to lambda closures that could
affect the program. Consider the following example
template<class T>
typename T::result_type foo(T); // Not defined
struct any {
template<class T>
any(T&&){}
};
void foo(any){}
int main() {
auto lambda = [] { return 42; };
foo(lambda);
}
If the compiler would add a nested type "result_type" to the lambda
closure, this would change the meaning of this program, in fact it would
now become undefined, because the function template is lacking
a definition.
I know that there are workarounds to make a closure type adaptable
(e.g. wrapping it in a std::function). I just want to know if it's
legal for a compiler to add these type members.
An implementation would not be conforming, if it did so.
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! ]