Topic: Lambdas as template arguments


Author: mrts.pydev@gmail.com
Date: Sun, 8 Apr 2012 08:15:02 -0700 (PDT)
Raw View
As far as I know, it is not currently possible to use labdas
as template arguments as there is no type that can be used
for representing them properly in template declarations.

Allowing lambdas as template arguments would be consistent
with the use of ordinary functions as template arguments.

This would open up many interesting possibilities     to name
one, implementing properties (an oft-requested feature for
C++) in expressive way would be trivial:

------------------------------------------------

struct S
{
   std::property<int,
     // getter
      [] (int&  value) { log(std::default_get(value)); },
     // setter, assignment not possible if omitted
      [] (int&  value, const int&  rhs) { log(std::default_set(value, rhs)); }>
         some_field;
};

------------------------------------------------


Here's a sample implementation where I use std::function as
a placeholder for the missing template-parameter-enabled
function type (does obviously not work as of now).

------------------------------------------------

template<typename T>
const T&  default_get(T&  value)
{ return value; }

template<typename T>
const T&  default_set(T&  value, const T&  rhs)
{ return value = rhs; }

template<typename T,
           std::function<const T&  (T&)>  get = default_get<T>,
           std::function<T&  (T&, const T&)>  set = default_set<T>>
class property
{
public:
     operator const T&  () const
     { return get(_value); }

     T&  operator= (const T&  rhs)
     { return set(_value, rhs); }

private:
     T _value;
};

------------------------------------------------


Note that the following is already possible with plain old
functions:

------------------------------------------------

template<typename T,
           const T&  (*get)(const T&) = default_get<T>,
           T&  (*set)(T&, const T&) = default_set<T>  >
class property
{
public:
     operator const T&  () const
     { return get(_value); }

     T&  operator= (const T&  rhs)
     { return set(_value, rhs); }

private:
     T _value;
};

------------------------------------------------

Feedback much appreciated,
best,
Mart S   mermaa


--
[ comp.std.c++ is moderated.  To submit articles, try posting with your ]
[ newsreader.  If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]




Author: =?windows-1252?Q?Daniel_Kr=FCgler?=<daniel.kruegler@googlemail.com>
Date: Tue, 10 Apr 2012 15:01:49 -0700 (PDT)
Raw View
On 2012-04-08 17:15, mrts.pydev@gmail.com wrote:
>  As far as I know, it is not currently possible to use labdas
>  as template arguments as there is no type that can be used
>  for representing them properly in template declarations.
>
>  Allowing lambdas as template arguments would be consistent
>  with the use of ordinary functions as template arguments.

Your description of the state is somhow misleading: There is no problem
at all to use a lambda closure type as template argument. From a
programmer's point of view, they are just class objects that override
the function call operator(). Templates have no problems with deducing
such a type.

>  This would open up many interesting possibilities     to name
>  one, implementing properties (an oft-requested feature for
>  C++) in expressive way would be trivial:
>
>  ------------------------------------------------
>
>  struct S
>  {
>      std::property<int,
>        // getter
>         [] (int&    value) { log(std::default_get(value)); },
>        // setter, assignment not possible if omitted
>         [] (int&    value, const int&    rhs) { log(std::default_set(value, rhs)); }>
>            some_field;
>  };
>
>  ------------------------------------------------

Yes, this usage of a lambda expression is not supported, which is due to
the restriction on (a) the valid types for non-type template parameters
and (b) the valid expressions used as argument to provide a value to
such a template parameter.

Regarding (a), I don't see why this is a particular problem for lambda
expressions (your rationale seems to imply that), because you cannot use
any function object type - except pointers to functions with linkage -
as non-type template parameter type.

Regarding (b) a lambda expression is not suitable as argument here
because of two reasons:

1) Even though a lambda expression without captures provides a
conversion to a function pointer, the lamba expressions is not a valid
expression form in this context (see [temp.arg.nontype] p1 b3).

2) A further problem is that the obtained function pointer does not
refer to a function with linkage.

I certainly agree that the current restrictions of non-type template
parameters (and their valid arguments) could and should be lifted to a
much higher extend, but I'm not sure that this solution is the right way
to solve your actual problem: Support for properties in C++.

Having several years of experience with languages that support
properties (notably Delphi), I can understand the wish for property
support, but I think this should be better fixed by a corresponding core
language extension. Extending the language just indirectly in the way
you suggest does not really solve the request. To me your declarations
don't look very appealing and I don't understand the particular reason
why you suggest to make the getter and setters of properties template
parameters. If I would try to provide a library extension for properties
(which I don't recommend for the reasons mentioned above), I would
design the property similar to std::function: You could just add a
callable object for the setter and the getter without affecting the type
of the property. With such an approach, lambda expressions would
naturally be supported.

HTH&  Greetings from Bremen,

Daniel Kr   gler



--
[ comp.std.c++ is moderated.  To submit articles, try posting with your ]
[ newsreader.  If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]