3

I wrote the following function that returns me the value of an integral_constant during compile-time such that I can use it in lambas with auto parameters:

template<typename T, T v> 
constexpr T Index(std::integral_constant<T, v>) { 
  return v; 
}

This function fails when using auto&& as the type of the passed integral_constant and I do not understand why.

I came up with an alternative solution that works and is more generic than my original example but leads to less understandable compiler errors:

auto Index2 = [](auto&& constant) { 
  return std::decay_t<decltype(constant)>::value; 
};

Now I want to use these functions in a lambda which gets passed an integral_constant but dependending on the type of the parameter i the first version fails:

int main() {

    auto f = [](auto i) {
        static_assert(Index(i) == 0);
        static_assert(Index2(i) == 0);
    };

    auto f2 = [](auto&& i) {
        static_assert(Index(i) == 0); //non-constant condition for static assertion
        static_assert(Index2(i) == 0);
    };

    f(std::integral_constant<int, 0> {});
    f2(std::integral_constant<int, 0> {});

}

I. e. I get the compiler error "non-constant condition for static assertion" but I do not understand why. While I'm fine with only using lambas like f, I would like to know why f2 fails to understand forwarding references / constexpr better.

Stefan Groth
  • 154
  • 7
  • Note that you gain nothing by passing integral constant as reference. Empty classes by value are much more lightweigh to pass a reference around. – Guillaume Racicot Aug 19 '19 at 15:16

0 Answers0