是否可以传递对 consteval 函数的引用并将其用作附加 return 值?
Is it possible to pass a reference to a consteval function and use it as additional return value?
有时函数的结果不能由单个 return 值表示。例如:相交两条线的函数。人们可能希望函数 return 实际交点以及它们之间的关系(即平行、相同、相交或倾斜)。
让我们假设这个例子,其中交点由某种 class 表示,线的位置关系由一个整数表示,该整数对 4 种可能性中的每一种都有一个指定值:
int IntersectLines(Line l1, Line l2, Point& point);
Point point{};
int result = IntersectLines(l1, l2, point);
这就是我今天实现它的方式,但现在我想知道是否可以有一个类似的实现,但具有 consteval 功能。 Line
和 Point
有 constexpr 构造函数和所有东西,计算本身也可以在编译时评估。唯一的问题是我想不出有两个 return 值的方法。我已经想到了 std::pair
但更类似于传递引用的解决方案将是首选。如果不存在这样的解决方案,我将不得不退回到 std::pair
.
通过引用 (Point& point
) 传递 point
是行不通的,因为“表达式未计算为常量”但传递const 引用 (const Point& point
) 也不起作用,因为我无法将结果分配给 point
。有没有办法让这个工作?
您不能传递对 consteval
函数的引用并让该函数修改引用的目标,除非您在另一个 consteval
函数中这样做。
对 consteval
函数的调用必须是一个常量表达式,前提是它没有在另一个 consteval
函数中调用。
但是,常量表达式不能修改常量表达式本身计算之外的对象。
在 consteval
和常用函数中,您可以 return 多个 return 值的 std::pair
或 std::tuple
,例如在调用站点将它们作为结构化绑定检索。
你可以return一个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
有时函数的结果不能由单个 return 值表示。例如:相交两条线的函数。人们可能希望函数 return 实际交点以及它们之间的关系(即平行、相同、相交或倾斜)。
让我们假设这个例子,其中交点由某种 class 表示,线的位置关系由一个整数表示,该整数对 4 种可能性中的每一种都有一个指定值:
int IntersectLines(Line l1, Line l2, Point& point);
Point point{};
int result = IntersectLines(l1, l2, point);
这就是我今天实现它的方式,但现在我想知道是否可以有一个类似的实现,但具有 consteval 功能。 Line
和 Point
有 constexpr 构造函数和所有东西,计算本身也可以在编译时评估。唯一的问题是我想不出有两个 return 值的方法。我已经想到了 std::pair
但更类似于传递引用的解决方案将是首选。如果不存在这样的解决方案,我将不得不退回到 std::pair
.
通过引用 (Point& point
) 传递 point
是行不通的,因为“表达式未计算为常量”但传递const 引用 (const Point& point
) 也不起作用,因为我无法将结果分配给 point
。有没有办法让这个工作?
您不能传递对 consteval
函数的引用并让该函数修改引用的目标,除非您在另一个 consteval
函数中这样做。
对 consteval
函数的调用必须是一个常量表达式,前提是它没有在另一个 consteval
函数中调用。
但是,常量表达式不能修改常量表达式本身计算之外的对象。
在 consteval
和常用函数中,您可以 return 多个 return 值的 std::pair
或 std::tuple
,例如在调用站点将它们作为结构化绑定检索。
你可以return一个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