2

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

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

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

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

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

point通过引用 ( )传递不起作用,Point& point因为“表达式没有计算为常量”,但通过 const 引用 ( const Point& point) 传递也不起作用,因为我无法将结果分配给point. 有没有办法让这个工作?

4

2 回答 2

3

您可以返回一个std::pair<Point, Relationship>.

例子:

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

演示

于 2022-02-26T14:44:11.610 回答
2

您不能传递对函数的引用consteval并让函数修改引用的目标,除非您在另一个consteval函数内部这样做。

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

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


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

于 2022-02-26T13:18:19.437 回答