Let's say we want to make a function which calculates the intersection point of two lines. The intersection point is't always defined or unique. How to reflect that in the function's signature?
I have come up with these options:
bool getIntersectionPoint ( Line& a, Line& b , Point& result );
Returns false if lines are parallel. Otherwise returns true and writes result to the variable.
Point getIntersectionPoint ( Line& a, Line& b );
Throws an exception if lines are parallel.
[update]
If we make 2 functions bool doLinesIntersect(const Line&, const Line&);
and Point twoLinesIntersection(const Line&, const Line&);
the second one can still be called after the first returns false.
IMHO, line intersection yields object, that's why it would be honest to have
boost::variant<Empty, Point, Line> intersect(Line const & l1, Line const & l2)
and helper functions, like
boost::optional<Point> getIntersectionPoint(Line const & l1, Line const & l2)
bool isParallel(Line const & l1, Line const & l2)
Edit: If you do not want to use boost library you can easily create simple analogues:
struct intersection_result_t
{
enum isec_t
{
isec_empty, isec_point, isec_line
}
intersection_result_t()
: type_(isec_empty)
{
new (storage_) Empty();
}
intersection_result_t(Empty const & e)
: type_(isec_empty)
{
new (storage_) Empty(e);
}
intersection_result_t(Point const & p)
: type_(isec_point)
{
new (storage_) Point(p);
}
...
intersection_result_t(intersection_result_t & ir)
: type_(ir.type_)
{
switch(ir.type_)
{
case isec_empty:
new (storage_) Empty(*static_cast<Empty*>(ir.storage_));
case ....
}
}
private:
void destroy()
{
switch(type_)
{
case isec_empty:
operator delete (static_cast<Empty*>(storage_), storage_);
case ....
}
}
private:
char storage_[MAX(sizeof(Empty), sizeof(Point), sizeof(Line))];
isec_t type_;
};
etc, etc some more switches needed. Or you can use templates.
For optional just use initialized_
instead of type_
to track construction state.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With