是否可以传递对 consteval 函数的引用并将其用作附加返回值?

发布于 2025-01-10 02:17:47 字数 712 浏览 1 评论 0原文

有时函数的结果不能用单个返回值表示。例如:与两条线相交的函数。人们可能希望该函数返回实际的交点以及它们之间的关系(即平行、相同、相交或倾斜)。

让我们假设这个例子,其中交点由某种类表示,线的位置关系由一个整数表示,该整数为 4 种可能性中的每一种保存指定的值:

int IntersectLines(Line l1, Line l2, Point& point);

Point point{};
int result = IntersectLines(l1, l2, point);

这就是我今天实现它的方式,但现在我我想知道是否可以有类似的实现,但具有 consteval 函数。 LinePoint 具有 constexpr 构造函数,所有内容和计算本身也可以在编译时进行评估。唯一的问题是我想不出有两种返回值的方法。我已经想到了 std::pair 但更喜欢传递引用的解决方案。如果这样的解决方案不存在,我将不得不退回到 std::pair 。

通过引用传递pointPoint& point)是行不通的,因为“表达式的计算结果不是常量”,而是通过const 引用 (const Point& point) 也不起作用,因为我无法将结果分配给 point。有办法让它发挥作用吗?

Sometimes the result of a function can not be represented by a single return value. For example: A function that intersects two lines. One might want the function to return both the actual point of intersection as well as their relation to each other (that is parallel, identical, intersecting or skewed).

Let us assume this example where the point of intersection is represented by some sort of class and the lines positional relation by an integer holding a specified value for each of the 4 possibilities:

int IntersectLines(Line l1, Line l2, Point& point);

Point point{};
int result = IntersectLines(l1, l2, point);

That is how I would have implemented it to this day but now I am wondering whether it is possible to have a similar implementation but with a consteval function. Line and Point have constexpr constructors and everything and the calculation itself can be compile time evaluated as well. The only problem is that I can't think of a way to have two return values. I already thought of std::pair but a solution more similar to passing a reference would be prefered. If such a solution doesn't exist I will have to fall back to std::pair.

It doesn't work by passing point by reference (Point& point) because "the expression did not evaluate to a constant" but passing by const reference (const Point& point) won't work either because I wouldn't be able to assign the result to point. Is there a way to get this working?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

爱本泡沫多脆弱 2025-01-17 02:17:47

您可以返回一个std::pair

示例:

consteval std::pair<Point, Relationship> IntersectLines(const Line& l1, const Line& l2) 
{
    // replace with the real calc below, this is just for show:
    const Point pnt{l1.p1.x + l2.p1.x, l1.p1.y + l2.p1.y};
    const Relationship rel = Relationship::parallel;
    return {pnt, rel};
}

并这样调用:

int main() {
    constexpr Line l1({1,2}, {3,4}), l2({5,6}, {7,8});
    constexpr auto pr = IntersectLines(l1, l2);
    auto&[pnt, rel] = pr;

    return pnt.x + pnt.y; // 14
}

通过优化,生成的程序集可能会变成类似

main:
        mov     eax, 14
        ret

Demo

You can return a std::pair<Point, Relationship>.

Example:

consteval std::pair<Point, Relationship> IntersectLines(const Line& l1, const Line& l2) 
{
    // replace with the real calc below, this is just for show:
    const Point pnt{l1.p1.x + l2.p1.x, l1.p1.y + l2.p1.y};
    const Relationship rel = Relationship::parallel;
    return {pnt, rel};
}

And call it like so:

int main() {
    constexpr Line l1({1,2}, {3,4}), l2({5,6}, {7,8});
    constexpr auto pr = IntersectLines(l1, l2);
    auto&[pnt, rel] = pr;

    return pnt.x + pnt.y; // 14
}

With optimization, the resulting assembly is likely to become something like

main:
        mov     eax, 14
        ret

Demo

橪书 2025-01-17 02:17:47

您不能将引用传递给 consteval 函数并让该函数修改引用的目标,除非您在另一个 consteval 函数内执行此操作。

对 consteval 函数的调用必须是其自身的常量表达式,假设它不是在另一个 consteval 函数内部调用的。

但是,常量表达式不能在常量表达式本身的计算之外修改对象。


然而,在 consteval 和普通函数中,您可以返回多个返回值的 std::pair 或 std::tuple ,例如检索它们在调用站点作为结构化绑定。

You cannot pass a reference to a consteval function and have the function modify the target of the reference, except if you do so in inside another consteval function.

The call to a consteval function must be on its own a constant expression, assuming it is not called inside another consteval function.

However, a constant expression cannot modify an object outside of the evaluation of the constant expression itself.


In both a consteval and usual function, you can however return a std::pair or std::tuple of multiple return values and e.g. retrieve them at the call site as a structured binding.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文