# How to pass a compile-time constant number to a generic lambda

**URL:** https://discourse.itk.org/t/how-to-pass-a-compile-time-constant-number-to-a-generic-lambda/4763
**Category:** Engineering
**Created:** [January 28, 2022, 2:42pm UTC](https://discourse.itk.org/t/how-to-pass-a-compile-time-constant-number-to-a-generic-lambda/4763 "2022-01-28T14:42:43Z")
**Posts on this page:** 10
**Page:** 1

<div class="post-metadata">

### Author: ![Niels\_Dekker](https://discourse.itk.org/letter_avatar_proxy/v4/letter/n/9d8465/32.png) [@Niels\_Dekker](https://discourse.itk.org/u/Niels_Dekker)
#### Post date: [January 28, 2022, 2:42pm UTC](https://discourse.itk.org/t/how-to-pass-a-compile-time-constant-number-to-a-generic-lambda/4763/1 "2022-01-28T14:42:43Z")

</div>

An interest use case for generic lambda’s: they allow passing a compile-time constant number, by using a `std::integral_constant` as function argument. For example:

```
auto genericLambda = [](const auto integralConstant) {

  constexpr auto constantValue = decltype(integralConstant)::value;

  float builtInArray[constantValue] = { 0.0f };

  itk::FixedArray<float, constantValue> fixedArray = { { 0.0f } };
};

// To be called, e.g., as follows:
genericLambda(std::integral_constant<unsigned int, 1U>{});
genericLambda(std::integral_constant<unsigned int, 2U>{});
genericLambda(std::integral_constant<unsigned int, 3U>{});

```

You see, this mitigates the limitation that you cannot explicitly specify the template arguments of a lambda. (C++14 does not support something like `genericLambda<42>()`.)

Unfortunately, this use case appears hampered by a VS2019 Visual C++ compiler bug! It produces a compile error on a similar code example: [Compiler Explorer](https://godbolt.org/z/6T53zP57a)

I just reported the bug to Microsoft: [Visual Studio Feedback](https://developercommunity.visualstudio.com/t/Compile-errors-generic-lambda-for-multip/1649123) and their reply was quite interesting! Xiaoxiao Xu [MSFT] replied that the compile error can be avoided by a compiler option!

> **[/Zc:lambda (Enable updated lambda processor)](https://docs.microsoft.com/en-us/cpp/build/reference/zc-lambda?view=msvc-170)**
>
> Learn more about: /Zc:lambda (Enable updated lambda processor)

Something to consider… if more of us are bothered by compiler bugs in the old “lambda processor” of Visual C++, maybe we could add this to our CMakeLists… what do you think?

---

<div class="post-metadata">

### Author: ![dzenanz](https://discourse.itk.org/user_avatar/discourse.itk.org/dzenanz/32/1093_2.png) [@dzenanz](https://discourse.itk.org/u/dzenanz)
#### Post date: [January 28, 2022, 2:58pm UTC](https://discourse.itk.org/t/how-to-pass-a-compile-time-constant-number-to-a-generic-lambda/4763/2 "2022-01-28T14:58:42Z")

</div>

I don’t mind enabling `/Zc:lambda`, but we should make sure to only enable it on VS2019 versions (16.8+?) which support it.

---

<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: [January 28, 2022, 3:07pm UTC](https://discourse.itk.org/t/how-to-pass-a-compile-time-constant-number-to-a-generic-lambda/4763/3 "2022-01-28T15:07:37Z")

</div>

We must remember that adding such a compile flag will require it for all applications that use ITK since ITK has a large template library component. It can be added to TK\_REQUIRED\_CXX\_FLAGS to do this. So these implications require some consideration.

However it’s not clear to me the if there is a real benefit to this usage in ITK, or just a convince of modern functions ( that are buggy and not widely used apparently ).

p.s. Thanks for the nice post and information on another approach. 🙃

---

<div class="post-metadata">

### Author: ![Niels\_Dekker](https://discourse.itk.org/letter_avatar_proxy/v4/letter/n/9d8465/32.png) [@Niels\_Dekker](https://discourse.itk.org/u/Niels_Dekker)
#### Post date: [January 28, 2022, 5:17pm UTC](https://discourse.itk.org/t/how-to-pass-a-compile-time-constant-number-to-a-generic-lambda/4763/4 "2022-01-28T17:17:24Z")

</div>

Thanks to you both for your feedback @dzenanz, @blowekamp

A use case for such generic lambda’s that I find interesting is a specific unit test that tests the same requirements for _1D_, _2D_, and _3D_ (or _ND_, in general). For example, the following lambda, `checkSizeFill`, would test `itk::Size<dimensionValue>::Fill` for any dimension.

```auto
TEST(Size, Fill)
{
  const auto checkSizeFill = [](const auto dimensionConstant) {

    for (const itk::SizeValueType sizeValue : { 0, 1, 2, INT_MAX })
    {
      itk::Size<dimensionConstant> actualSize;
      actualSize.Fill(sizeValue);
      const auto expectedSize = itk::Size<dimensionConstant>::Filled(sizeValue);
      EXPECT_EQ(actualSize, expectedSize);
    }
  };

  // Check itk::Size::Fill for 1D, 2D, and 3D:
  checkSizeFill(std::integral_constant<unsigned int, 1>{});
  checkSizeFill(std::integral_constant<unsigned int, 2>{});
  checkSizeFill(std::integral_constant<unsigned int, 3>{});
}

```

This `checkSizeFill` still compiles fine with VS2019. Those buggy compile errors only appear when the generic lambda gets somewhat more complicated!

Note that we can make it still more beautiful by introducing an `itk::DimensionConstant` alias, to allow writing:

```auto
  // Check itk::Size::Fill for 1D, 2D, and 3D:
  checkSizeFill(itk::DimensionConstant<1>{});
  checkSizeFill(itk::DimensionConstant<2>{});
  checkSizeFill(itk::DimensionConstant<3>{});

```

Do you like it? 😃

* * *

Edit: Removed `decltype(dimensionConstant)::value` from the example – it appears unnecessary 😃

---

<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: [January 28, 2022, 5:44pm UTC](https://discourse.itk.org/t/how-to-pass-a-compile-time-constant-number-to-a-generic-lambda/4763/5 "2022-01-28T17:44:53Z")

</div>

> [@Niels\_Dekker](#):
>
> Do you like it? 😃

I agree. It is interesting. Can’t you just use a template function? Or use a google test fixture and make it a member function.

What is the advantage of a lambda here? I was expecting some variadic initializer list, but this seems simpler and with alternatives.

---

<div class="post-metadata">

### Author: ![Niels\_Dekker](https://discourse.itk.org/letter_avatar_proxy/v4/letter/n/9d8465/32.png) [@Niels\_Dekker](https://discourse.itk.org/u/Niels_Dekker)
#### Post date: [January 28, 2022, 5:54pm UTC](https://discourse.itk.org/t/how-to-pass-a-compile-time-constant-number-to-a-generic-lambda/4763/6 "2022-01-28T17:54:17Z")

</div>

> [@blowekamp](#):
>
> Can’t you just use a template function? Or use a google test fixture and make it a member function.

Sure, technically, a `checkSizeFill<ImageDimension>` could also be written as a template function, or a member function. But in this specific case, it seems preferable to keep `checkSizeFill` local, within the definition of `TEST(Size, Fill)`. Because it would not be used elsewhere. Just like ordinary local variables are often preferable to globals, or even member variables.

---

<div class="post-metadata">

### Author: ![Lee\_Newberg](https://discourse.itk.org/user_avatar/discourse.itk.org/lee_newberg/32/1461_2.png) [@Lee\_Newberg](https://discourse.itk.org/u/Lee_Newberg)
#### Post date: [January 28, 2022, 5:58pm UTC](https://discourse.itk.org/t/how-to-pass-a-compile-time-constant-number-to-a-generic-lambda/4763/7 "2022-01-28T17:58:02Z")

</div>

Especially in testing code it might be simpler to introduce a templated helper class. Approaches could vary, but the helper class might have the tested class’s template parameters, and an extra `int N` parameter if that’s not already one of the parameters. The helper class’s methods would probably not need additional template parameters.

---

<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: [January 28, 2022, 6:07pm UTC](https://discourse.itk.org/t/how-to-pass-a-compile-time-constant-number-to-a-generic-lambda/4763/8 "2022-01-28T18:07:12Z")

</div>

> [@Niels\_Dekker](#):
>
> But in this specific case, it seems preferable to keep `checkSizeFill` local

There are anonymous namespaces introduces some time before C++03 that would keep it local to the file, which should be local enough.

BTW @Niels_Dekker I tried to ping you on a [PR in SimpleITK](https://github.com/SimpleITK/SimpleITK/pull/1572) with some very interesting variadic templates for typelists that I thought you would find interesting. Here is one class implementation of particular interest:

```auto
template <typename... Tls, typename... Trs>
 struct dual_visit<typelist<Tls...>, typelist<Trs...>>
 {
   template <typename Visitor>
   void
   operator()(Visitor && visitor) const
   {
     (void)std::initializer_list<int>{ right_visit<Tls>(visitor)... };
   }

 private:
   template <typename tl, typename tr, typename Predicate>
   static int
   visit_value(Predicate && visitor)
   {
     visitor.CLANG_TEMPLATE operator()<tl, tr>();
     return 0;
   }

   template <typename tl, typename Predicate>
   static int
   right_visit(Predicate && visitor)
   {
     (void)std::initializer_list<int>{ visit_value<tl, Trs>(visitor)... };
     return 0;
   }
 };

```

💪

---

<div class="post-metadata">

### Author: ![Niels\_Dekker](https://discourse.itk.org/letter_avatar_proxy/v4/letter/n/9d8465/32.png) [@Niels\_Dekker](https://discourse.itk.org/u/Niels_Dekker)
#### Post date: [January 28, 2022, 6:38pm UTC](https://discourse.itk.org/t/how-to-pass-a-compile-time-constant-number-to-a-generic-lambda/4763/9 "2022-01-28T18:38:12Z")

</div>

@blowekamp Very interesting, your typelist update!

> [@blowekamp](#):
>
> There are anonymous namespaces introduces some time before C++03 that would keep it local to the file, which should be local enough.

Again, I think generic lambda’s are a useful tool to keep functionality local to their usage. But I’m sorry if I cannot convince either you @blowekamp, @Lee_Newberg

Just for clarification, I encounter situations that look like this:

```auto
namespace
{
template <int> void TestAlpha() { /* Test alpha */ }

template <int> void TestBeta() { /* Test beta */ }

template <int> void TestDelta() { /* Test delta */ }

template <int> void TestOmicron() { /* Test omicron */ }
} // namespace

TEST(Covid, Alpha)
{
  TestAlpha<1>();
  TestAlpha<2>();
  TestAlpha<3>();
}

TEST(Covid, Beta)
{
  TestBeta<1>();
  TestBeta<2>();
  TestBeta<3>();
}

TEST(Covid, Delta)
{
  TestDelta<1>();
  TestDelta<2>();
  TestDelta<3>();
}

TEST(Covid, Omicron)
{
  TestOmicron<1>();
  TestOmicron<2>();
  TestOmicron<3>();
}

```

You see, each of the function templates here is _only relevant_ to the corresponding unit test. Having all those helper function templates “dumped” into the namespace that is shared between all the unit tests in the file seems suboptimal to me. If it doesn’t convince you, at least I hope I made my point clear.

---

<div class="post-metadata">

### Author: ![Niels\_Dekker](https://discourse.itk.org/letter_avatar_proxy/v4/letter/n/9d8465/32.png) [@Niels\_Dekker](https://discourse.itk.org/u/Niels_Dekker)
#### Post date: [February 6, 2022, 4:10pm UTC](https://discourse.itk.org/t/how-to-pass-a-compile-time-constant-number-to-a-generic-lambda/4763/10 "2022-02-06T16:10:41Z")

</div>

For the record, a `TEST(Size, Fill)` implementation similar to the example code that I posted [here](https://discourse.itk.org/t/how-to-pass-a-compile-time-constant-number-to-a-generic-lambda/4763/4) (but still slightly improved) is now include with the `itk::Size` GoogleTest:

> <https://github.com/InsightSoftwareConsortium/ITK/blob/9783af0c3c18ef708f5ff5c161d9b96ba367ee09/Modules/Core/Common/test/itkSizeGTest.cxx#L104-L124>

From pull request [https://github.com/InsightSoftwareConsortium/ITK/pull/3157](https://github.com/InsightSoftwareConsortium/ITK/pull/3157)
