# New Functor Filter with lambda support

**URL:** <https://discourse.itk.org/t/new-functor-filter-with-lambda-support/899>\
**Category:** Engineering\
**Created:** [May 3, 2018, 8:27pm UTC](https://discourse.itk.org/t/new-functor-filter-with-lambda-support/899 "2018-05-03T20:27:18Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![blowekamp](https://discourse.itk.org/user_avatar/discourse.itk.org/blowekamp/32/79_2.png) [@blowekamp](https://discourse.itk.org/u/blowekamp)\
**Post date:** [May 3, 2018, 8:27pm UTC](https://discourse.itk.org/t/new-functor-filter-with-lambda-support/899/1 "2018-05-03T20:27:18Z")

</div>

This is in regards to the following topic: [http://review.source.kitware.com/#/c/23352/](http://review.source.kitware.com/#/c/23352/)

This patch introduces the UnaryGeneratorImageFilter BinaryGeneratorImageFilters, as replacements for the UnaryFunctorImageFilter and the BinaryFunctorImageFilters. The two big advantages are:

- Support for C++ lambda’s
- Removed class’s template parameter for functor, which enables reuse of a parent class.

These new classes enable the setting for the functor with a “SetFunctor” method, where the type of functor is specified when the method is envoked as opposed to being a class argument. This enables the following uses:

```auto
using FilterType = itk::UnaryGeneratorImageFilter<ImageType, ImageType>;
using ValueFunctionType = FilterType::ValueFunctionType;

auto filter = FilterType::New();

// set with C style function pointer
filter->SetFunctor( static_cast<ValueFunctionType*>(std::cos) );

// set with std::functional
std::function<float(float)> func1 = static_cast<ValueFunctionType*>(std::sin);
filter->SetFunctor( func1 );

// set with C++ lambda function
filter->SetFunctor( [](const float &v) { return v+2.0;});

```

In addition to the itk::Functors from the same namespace.

The implementation passes the functor type to a `ThreadedGenerateData` method so that the functor can be inlined, and the filters can retain the efficiency. Additionally, the filter no longer holds a direct copy of the functor, to when `SetFunctor` is called a copy of the argument is captured in a lambda expression, and that copy is not accessible.

---

<div class="post-metadata">

**Author:** ![phcerdan](https://discourse.itk.org/user_avatar/discourse.itk.org/phcerdan/32/286_2.png) [@phcerdan](https://discourse.itk.org/u/phcerdan)\
**Post date:** [May 4, 2018, 10:13am UTC](https://discourse.itk.org/t/new-functor-filter-with-lambda-support/899/2 "2018-05-04T10:13:07Z")

</div>

Wow, this is great!!

---

<div class="post-metadata">

**Author:** ![blowekamp](https://discourse.itk.org/user_avatar/discourse.itk.org/blowekamp/32/79_2.png) [@blowekamp](https://discourse.itk.org/u/blowekamp)\
**Post date:** [May 4, 2018, 12:54pm UTC](https://discourse.itk.org/t/new-functor-filter-with-lambda-support/899/3 "2018-05-04T12:54:04Z")

</div>

The following are the signatures added for “SetFunctor”:

```auto
  using ConstRefFunctionType = OutputImagePixelType (const Input1ImagePixelType &,
                                                     const Input2ImagePixelType &);
  using ValueFunctionType = OutputImagePixelType (Input1ImagePixelType,
                                                  Input2ImagePixelType);

  /** Set the pixel functor
   *
   * The functor defines an operation done per pixel.
   */
 void SetFunctor( const std::function<ConstRefFunctionType> &f);
 void SetFunctor( const std::function<ValueFunctionType> &f);

  /** Set the pixel functor by a C function pointer
   *
   * The functor defines an operation done per pixel.
   */
  void SetFunctor( ConstRefFunctionType *funcPointer);
  void SetFunctor( ValueFunctionType *funcPointer);

  /** Set the pixel functor by a "Functor Object"
   *
   * The functor defines an operation done per pixel. A single copy of
   * the argument is created an used for all threads, so the functor
   * must be concurrent thread-safe. The functor must a have an
   * operator() method which accept arguments of Input1ImagePixelType,
   * Input2ImagePixelType.
   */
  template <typename TFunctor>
  void SetFunctor( const TFunctor &functor);

```

So these signatures accept the C++ lambdas, C++ `std::function`s, C-Style function pointers, and ITK Style functors. The one negative thing is that the last template `SetFunctor`has no constraints so if “junk” is passed to it then an obscure compiler error message can be generated.

Also passing `SetFunctor` C++ lambda, will use the templated signature. While the type of a lambda can be converted to a `std::function`, the `SetFunction`’ temple signature has higher priority than implicitly converting to `std::function`. Because the template signature is used there is no enforcement of the specific arguments and return type for the lambda ( neither is there for the ITK Functors either ).

So this current approach has chosen flexibility over strong typing for the `SetFunctor` argument. Is there any options or feedback from the modern C++ gurus around?

---

<div class="post-metadata">

**Author:** ![blowekamp](https://discourse.itk.org/user_avatar/discourse.itk.org/blowekamp/32/79_2.png) [@blowekamp](https://discourse.itk.org/u/blowekamp)\
**Post date:** [May 5, 2018, 1:52pm UTC](https://discourse.itk.org/t/new-functor-filter-with-lambda-support/899/4 "2018-05-05T13:52:44Z")

</div>

The native ITK Python will need some updates following this patch.

- The new Generator classes need to be directly wrapped
- The old Functor wrapping convention of wrapping the superclass:

```auto
itk_wrap_class("itk::TanImageFilter" POINTER_WITH_SUPERCLASS)
  itk_wrap_image_filter("${WRAP_ITK_REAL}" 2)
itk_end_wrap_class()

```

Should be removed. This manifestation of the benefit of reduced generated code an symbols so it should have the benefit of improving compilation time and reduce binary size.

I presume one can programmatically generate a list of classes now derived from the Generator filters and programmatically remove `POINTER_WITH_SUPERCLASS` form the .wrap file.

Are there any volunteers?

---

<div class="post-metadata">

**Author:** ![matt.mccormick](https://discourse.itk.org/user_avatar/discourse.itk.org/matt.mccormick/32/7_2.png) [@matt.mccormick](https://discourse.itk.org/u/matt.mccormick)\
**Post date:** [May 6, 2018, 1:24am UTC](https://discourse.itk.org/t/new-functor-filter-with-lambda-support/899/5 "2018-05-06T01:24:56Z")

</div>

It is excellent we have this feature – thanks again for contributing this @blowekamp !

I will look into fixing the Python wrapping.

---

<div class="post-metadata">

**Author:** ![spinicist](https://discourse.itk.org/user_avatar/discourse.itk.org/spinicist/32/183_2.png) [@spinicist](https://discourse.itk.org/u/spinicist)\
**Post date:** [September 5, 2018, 11:02am UTC](https://discourse.itk.org/t/new-functor-filter-with-lambda-support/899/6 "2018-09-05T11:02:40Z")

</div>

I’ve just converted one of my programs to use this - it’s great! All the boilerplate to do with the `Functor` objects is gone.
