具有不同返回类型的C++函数
C++ function with different return types
假设我想写一个函数,它取R^3中的一个平面和一条线,并返回它们的交集。显然,我必须区分三种可能的情况:I(直线与平面在一个点相交,ii(直线是平面的子集,iii(直线平行于平面(而不是平面的子集(。这导致函数有三种可能的返回类型。
我最近一直在使用OCaml,这将使我能够通过从函数中返回一个变体类型来非常明确地区分这些不同的类型。在C++中,人们是如何处理这类问题的?
脑海中浮现的一个想法是使用{bool,bool,vector}的元组作为我的返回类型,其中第一个布尔值表示直线和平面是否有非空相交,第二个布尔值则表示如果第一个布尔为真,它们是否在一个点相交(否则毫无意义(,如果两个布尔值都为真(否则就没有意义(,则向量返回唯一的交集。然而,这感觉非常不雅和笨拙,我必须使用注释通知用户元组条目的含义,我返回可能没有意义的变量,等等。
处理这个问题的最佳方法是什么?
这里有几种通用(即不限于几何线和点(方法来处理这个问题。
std::variant
(对于那些不能运行C++17的人来说,是它的老兄弟boost::variant
(-
普通旧工会(已标记(:
struct LinePlaneIntersection { enum { IsLine, IsPlane } intersection_type; union { Point p; Line l; }; };
如果
Point
和Line
具有非平凡的构造函数和/或析构函数,则需要将actor和dtor添加到上述方案中。 -
朴素的古老遗产。
class LinePlaneIntersection { ... }; class NoIntersection : public LinePlaneIntersection { ... }; class OnePointIntersection : public LinePlaneIntersection { ... }; class OneLineIntersection : public LinePlaneIntersection { ... };
从函数中返回一个
LinePlaneIntersection*
(或更好、更可取的std::unique_ptr<LinePlaneIntersection>
(。当然,还有一个问题是如何处理返回的值。您可能需要在此处使用访问者模式。 -
继续通过。不要返回任何内容,而是接受继续。在这种情况下,有三个延续:
void intersect (Line line, Plane plane, std::function<void(Line)> onLine, std::function<void(Point)> onPoint, std::function<void()> onNothing);
我会做一些类似的事情:
struct Point3D
{
double x;
double y;
double z;
};
struct Line
{
Point3D p1;
Point3D p2;
};
struct Plan {
Point3D p;
Point3D orthogonalDir;
};
std::optional<std::variant<Point3D, Line>>
ComputeIntersection(const Line& line, const Plan& plan);
尽管有很好的新方法来处理这一问题(std::tuple
、std::variant
和c.(,但久经考验的方法是设计一个class
(甚至一组相关类(,它可以表示各种状态并返回其实例。
随着项目的发展,这种方法似乎总是能最好地扩展。如此之多,以至于Java背后的委员会从未向他们的语言和库中发出元组或变体类型。
为什么不返回具有枚举类型的结构?使用该功能的人可以在尝试使用数据之前先检查交叉口的类型。
enum IntersectType {
INTERSECTION_NONE,
INTERSECTION_POINT,
INTERSECTION_LINE,
};
struct Point3D {
double x;
double y;
double z;
}
struct LinePlaneIntersect {
IntersectType type;
std::vector<Point3D> intersect; //since you mentioned vector
};
//Check within another function
struct LinePlaneIntersect intersection = fun(line, plane);
if (intersection.type == INTERSECTION_POINT) {
// do something
}
- "error: no matching function for call to"构造函数错误
- 什么时候调用组成单元对象的析构函数
- 继承函数的重载解析
- 为什么随机数生成器不在void函数中随机化数字,而在main函数中随机化
- C++模板来检查友元函数的存在
- 递归函数计算序列中的平方和(并输出过程)
- 对RValue对象调用的LValue ref限定成员函数
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 在C++STL中是否有Polyval(Matlab函数)等价物?
- 为什么使用 "this" 指针调用派生成员函数?
- 将对象数组的引用传递给函数
- 函数调用中参数的顺序重要吗
- 函数向量_指针有不同的原型,我可以构建一个吗
- 使用不带参数的函数访问结构元素
- 代码在main()中运行,但在函数中出现错误
- 内置函数可查看CPP中的成员变量
- 如何获取std::result_of函数的返回类型
- 如何在c++中为模板函数实例创建快捷方式
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗