Adam Butcher wrote:
Hopefully. From my point of view the class generated by a lambda expression
should be equivalent to something you
could write yourself -- aside from the single stack-pointer reference
optimization which only a compiler could achieve
-- the class has a name, albeit invisible to the user (except in
errors/warnings), and instances of should be useable
just as if there were user-defined functors. I'm sure there are things I've
overlooked but hopefully this
proof-of-concept will help to allay people's fears.
In my opinion, lambdas are not intended as just a shortcut to writing a
function object class. This is why our proposal did not require that
lambdas be implemented as classes; it is simply one implementation.
(Awaiting word to see if this is still the case in the working draft of
the standard; it may not be, but that doesn't change my opinion :)
Thus, users should never see the class name. In warnings and errors, a
lambda should be treated like an anonymous class, swapping its
compiler-generated name with a placeholder like <lambda function>
(similar to <anonymous class>). Additionally, users should never be
able to instantiate a function call operator member, as below:
Makes sense. I suppose to specify explicit template arguments users
would have to write
lambdaob.operator()<template-arg>(fn-arg)
That would be the case for explicit instantiation yes. With my implementation you could only get such as nullary
function template if you explicitly specified the template parameters and
explicitly specified an empty call argument
list. I've made the template parameter list optional within the already
optional lambda-parameter-declaration. If
present, it has to be followed by a function parameter list. The intent of
course is that any template parameters
will be referenced in the function parameter list. Though it does not prevent
having unreferenced template parameters
that would need to be explicitly bound.
If a higher-order function were to accept a "function-like object" and
instantiate its function call operator member, then it is using it as a
class, and should not pretend to accept function pointers or lambdas.
The argument types of a lambda function can be deduced from the context
of the lambda expression, meaning a template constant lambda function
should never be necessary.
Since templates work so differently from normal functions, I'm a little
uncomfortable with the idea of templates that don't involve any template
syntax, just the use of auto in the parameter list. But I'm open to
giving it a try, at least in the lambda context. Maybe outside of
lambda it could be used with a small template introducer...
In response to Jason's concern here, a template implementation is not
required, just convenient. Hopefully you won't think of it as
"templates without template syntax", but "deduction using the existing
template mechanism".
[snip] The benefit
of using it in lambdas is that the call operator is never 'seen', so whether
its a template or not shouldn't affect
the caller providing the input arguments are compatible.
Exactly.
so we'd really expect them to be only deduced.
Yes.
Exactly.
When I last left the discussion, the biggest
issue in my opinion was concept map dropping. The workaround made the
deduction algorithm intimidatingly complex.
I am not up to speed with the issues but they obviously exist. One thing I
don't understand, and perhaps you could
help, is that whatever issues polymorphic lambdas have -- surely manually
written function objects with template call
operators have the same issues. Is this true?
We did not want (and I doubt a concept proposal would approve)
polymorphic lambdas to interrupt the modular type checking of
constrained templates, i.e. templates using concepts, so the constraints
would have to be deduced and added to the function call operator (in a
class implementation for lambdas). Hand-written function object classes
bypass this issue by not allowing the deduction of constraints - they
must be hand-written if the function object class is to be used in a
constrained context.
And if so does it mean that future standard library algorithms will be
more constraining than exisiting ones -- or am I barking up the wrong tree?
When concepts come, standard library algorithms /will/ be constrained,
but not to disallow any correct uses. The constraints /will/ expose
improper uses of the standard library.
- John