3

Suppose you have a scenario when you want to create a constexpr lambda inside a method for calculating something at compile time.

struct A {
    int a;
    constexpr A(int a) : a(a) {}
    constexpr auto operator+(const A& rhs) {
        constexpr auto l = [&]() {
            return A(this->a + rhs.a);
        };
        return l();
    }
};

This code doesn't compile because compiler said that this and rhs are not constant expressions. Is there a way for passing this and rhs to a local constexpr lambda?

Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
apopa
  • 405
  • 2
  • 12
  • What is the point of using the lambda at all? Why not just `constexpr auto operator+(const A& rhs) { return a + rhs.a; }`? – Remy Lebeau Aug 31 '21 at 23:13
  • 1
    @RemyLebeau Perhaps the posted code is just a *minimal* example of what is being sought? In OP's 'real-world' code, there may be a more justifiably reason to want a lambda. – Adrian Mole Aug 31 '21 at 23:28
  • Yes, you are right @Adrian. It is just a minimal example. – apopa Aug 31 '21 at 23:39

1 Answers1

3

You can't capture the a members of this and rhs (by reference) and maintain constexpr validity1; however, you can pass those members as by (const) reference arguments to your lambda:

struct A {
    int a;
    constexpr A(int a) : a(a) { }
    constexpr auto operator+(const A rhs) {
        constexpr auto l = [](const int& ta, const int& ra) {
            return A(ta + ra);
        };
        return l(a, rhs.a); // Or return l(this->a, rhs.a) if you prefer
    }
};

1 Or maybe you can, but it's messy: Lambda capture as const reference?

Adrian Mole
  • 49,934
  • 160
  • 51
  • 83