If you can afford Boost then this sounds like a perfect application for Boost.Variant.
struct NoIntersection {
// empty
};
struct Point {
// whatever
};
struct Circle {
// whatever
};
typedef boost::variant<NoIntersection, Point, Circle> IntersectionResult;
IntersectionResult intersection_test() {
if(some_condition){
return NoIntersection();
}
if(other_condition){
return Point(x, y);
}
if(another_condition){
return Circle(c, r);
}
throw std::runtime_error("unexpected");
}
You then process your result with a static visitor:
struct process_result_visitor : public boost::static_visitor<> {
void operator()(NoIntersection) {
std::cout << "there was no intersection
";
}
void operator()(Point const &pnt) {
std::cout << "there was a point intersection
";
}
void operator()(Circle const &circle) {
std::cout << "there was a circle intersection
";
}
};
IntersectionResult result = intersection_test();
boost::apply_visitor(process_result_visitor(), result);
EDIT: The visitor class must derive from boost::static_visitor
UPDATE: Prompted by some critical comments I've written a little benchmark program. Four approaches are compared:
boost::variant
- union
- class hierarchy
boost::any
These are the results in my home computer, when I compile in release mode with default optimizations (VC08):
test with boost::variant took 0.011 microseconds
test with union took 0.012 microseconds
test with hierarchy took 0.227 microseconds
test with boost::any took 0.188 microseconds
Using boost::variant
is faster than a union and leads (IMO) to the most elegant code. I'd guess that the extremely poor performance of the class hierarchy approach is due to the need to use dynamic memory allocations and dynamic dispatch. boost::any
is neither fast nor especially elegant so I wouldn't consider it for this task (it has other applications though)
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…