Home > OS >  consteval lambda with ignored parameter doesn't compile
consteval lambda with ignored parameter doesn't compile

Time:11-09

I have a lambda that ignores its int parameter and always returns a constant. If I mark it consteval, compilation fails because. The compiler complains about invoking the consteval lambda with a non-const parameter. But what does the parameter has to do with the lambda?

From CompilerExplorer:

source:3:16: error: the value of 'i' is not usable in a constant expression 5 | lambda(i);

void bar (auto lambda, int start, int end) {
    for (int i=start; i<end;   i) {
        lambda(i);
    }
}

int main( )
{
    auto foo = [] (int) consteval { return 2;};

    bar(foo, 1, 9);

    return 0;
}

CodePudding user response:

One way to solve this(and the simplest) is to change the parameter type of the lambda to int& so that it doesn't need to read the value, as shown below:

int main( )
{//-------------------v------------------------->reference added
    auto foo = [] (int&) consteval { return 2;};

    bar(foo, 1, 9);

    return 0;
}

Working demo

Here is another contrived example that has similar behavior:

template<typename T>
consteval int func(const T) //note NO REFERENCE HERE
{
    return std::is_integral<T>::value;;
}

template<typename T>
//-----------------------v----->note the reference here
consteval int bar(const T&)
{
    return std::is_integral<T>::value;;
}

int main()
{
    
    int p = 2;
    //constexpr int d = func(p); //doesn't work
    constexpr int f = bar(p); //works

}

Contrived example demo

CodePudding user response:

You can also add an explicit check. Not the most elegant solution, but yeah:

#include <type_traits>

void bar(auto lambda, int start, int end) {
    for (int i = start; i < end;   i) {
        if constexpr (std::is_invocable_v<decltype(lambda)>) {
            lambda();
        } else {
            lambda(i);
        }
    }
}

int main() {
    bar([] () consteval { return 2; }, 1, 9);
    bar([](int) { return 2; }, 1, 9);

    return 0;
}
  • Related