{ edited by mod: quoted signature and server banner redacted. -mod }
On Tuesday, April 12, 2016 at 6:50:12 AM UTC-5, Juan Pedro Bolivar Puente
wrote:
> Hi!
>
> Thanks a lot for your response, it's inspiring...
>
> > The difficult problem with lambdas is that they are not constexpr.
>
> Agreed...
>
> > In the Fit library[1], I would like to support the factory pattern for
> > lambdas, so you could write this:
> >
> > auto lambda_factor()
> > {
> > return []{ ... };
> > }
> >
> > FIT_STATIC_FUNCTION(lambda) = fit::indirect(&lambda_factor, fit::apply);
> >
> > The fit::indirect adaptor needs to be extended to support a custom
> > operator.
>
> That sounds interesting, but if I am understanding this correctly after
> looking at the Fit code, this will call `lambda_factor` via a function
> pointer whenever we want to call `lambda`. While there is some chance
> that it will still be inlined, I don't totally like it.
The function pointer is initialized at compile-time, so it is very likely to
be inlined.
> I guess an
> alternative, but again more boilerplaty, would be to write something like:
>
> struct lambda_factor
> {
> auto operator()
> {
> return [] { ... };
> }
> };
>
> FIT_STATIC_FUNCTION(lambda) = fit::indirect2<lambda_factor>(...);
Yes a function object could be used as well. I don't know what the
`indirect2`
does. It could be written like this:
struct lambda_factor
{
auto operator()() const
{
return [] { ... };
}
};
FIT_STATIC_FUNCTION(lambda) = fit::indirect(lambda_factor{}, fit::apply);
>
> All this could maybe be wrapped in a macro such one could write
> something like:
>
> FIT_GLOBAL_LAMBDA(lambda, ([] {
> ...
> }));
>
> but admittedly it does not feel very nice...
The biggest problem with the macro like that is that the lambda is expanded
in
the macro itself which can make debugging problematic. In general, macros
should be used for things that are declarative. An alternative approach like
this could possible work, but I haven't tried it:
#define FIT_STATIC_FACTORY(name) \
struct name ## _factory { auto operator()() const; } \
FIT_STATIC_FUNCTION(name) = fit::indirect(name ## _factory{}, fit::apply); \
auto name ## _factory::operator()() const
So then you should be able to write:
FIT_STATIC_FACTORY(lambda)
{
return [] { ... };
}
Of course, fit::indirect doesn't support a custom operator yet, so until
then,
it could possibly be written like this using the dereference operator
instead:
#define FIT_STATIC_FACTORY(name) \
struct name ## _factory { auto operator*() const; } \
FIT_STATIC_FUNCTION(name) = fit::indirect(name ## _factory{}); \
auto name ## _factory::operator*() const
>
> I hope the standard eventually tackles the problem, ideally by making
> lambdas constexpr if needed, but I do understand that the problem is
> hard for the C++ compilation model...
I believe C++17 is on track for constexpr lambdas which would simplify part
of
it. The other part is to support inline variables so the dance with template
variables or static class variables is unnecessary, but I don't know how far
the committee has gotten with that. Hopefully, in C++17 we will be able to
just write:
extern constexpr auto lambda = [] { ... };
And thats it.
Paul