英文:
Using operators on a custom type in a lambda at compile time in C++
问题
我有一个类,我想在编译时执行操作。在下面的示例中,我有一个简单的结构体IntWrapper,其中重载了operator+。在任何正常情况下使用这个类似乎都没问题,但在lambda内部使用时会失败,为什么?
struct IntWrapper
{
	consteval IntWrapper operator+(const IntWrapper& other) const
	{
		return { x + other.x };
	}
	int x;
};
int main()
{
	// 正常情况下加法运算工作正常
	constexpr IntWrapper c1 = IntWrapper{ 1 } + IntWrapper{ 1 };
	auto adder = [](IntWrapper x) { return x + x; };
	// 在lambda内部使用加法不起作用
	constexpr IntWrapper c2 = adder(IntWrapper{ 1 });
}
如何使这个对象在lambda的上下文中在编译时工作?
英文:
I have a class which I'd like to perform operations on at compile time. In the example below I have a simple struct IntWrapper with an overloaded operator+. Using this class in any normal context seems to work fine, but it fails when used inside a lambda, why?
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 });
}
How can I get this object to work, at compile time, inside the context of a lambda?
答案1
得分: 5
使用旧的C++20规则,x + x作为x.operator+(x)必须是一个常量表达式,因为它调用了一个consteval函数,但它本身不在一个consteval函数内部。由于它使用了函数参数的值,它不能是一个常量表达式。
将其放在一个consteval函数内部:
auto adder = [](IntWrapper x) consteval { return x + x; };
这在P2564R3中已得到修复,因此遵循新规则的编译器(如clang 17)将在C++20模式下编译此代码。
英文:
Using the old C++20 rules, x + x being x.operator+(x) must be a constant expression, since it calls a consteval function but is not inside a consteval function itself. It can't be a constant expression since it uses the function argument's values.
Make it be inside a consteval function:
auto adder = [](IntWrapper x) consteval { return x + x; };
This is fixed with P2564R3 so a compiler following the new rules (like clang 17) will compile this, even in C++20 mode.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论