在 C++ 编译时在 lambda 中的自定义类型上使用运算符

Mat*_*uir 1 c++ lambda constexpr

我有一个类,我想在编译时对其执行操作。在下面的示例中,我有一个IntWrapper带有重载的简单结构operator+。在任何正常上下文中使用此类似乎都可以正常工作,但在 lambda 内部使用时会失败,为什么?

struct IntWrapper
{
    consteval IntWrapper operator+(const IntWrapper& other) const
    {
        return { x + other.x };
    }

    int x;
};

int main()
{
    // Adding normally works just fine
    constexpr IntWrapper c1 = IntWrapper{ 1 } + IntWrapper{ 1 };

    auto adder = [](IntWrapper x) { return x + x; };

    // Using a lambda to add doesn't work
    constexpr IntWrapper c2 = adder(IntWrapper{ 1 });
}
Run Code Online (Sandbox Code Playgroud)

我怎样才能让这个对象在编译时在 lambda 上下文中工作?

Art*_*yer 5

使用旧的 C++20 规则,x + xbeingx.operator+(x)必须是常量表达式,因为它调用函数consteval但不在consteval函数本身内部。它不能是常量表达式,因为它使用函数参数的值。

使其位于consteval函数内部:

auto adder = [](IntWrapper x) consteval { return x + x; };
Run Code Online (Sandbox Code Playgroud)

P2564R3已修复此问题,因此遵循新规则(如 clang 17)的编译器将对其进行编译,即使在 C++20 模式下也是如此。