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

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.

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:

  // 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? :smiley:


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