[polygon] Overload resolution for operators fails

Hi Luke and polygonists, trying to set up some law based tests for boost::polygon I faced difficulties with the overload resolution of operators under msvc-9. This is the code sniplet where the problems occur: ----------------------------------------------------------- #include <boost/validate/laws/law.hpp> #include <boost/polygon/polygon.hpp> // Here I map a PolygonSet class to geometry_concepts according to // the docs: #include <boost/itl_xt/custom_polygon.hpp> namespace boost{namespace itl { template <typename Type> class PolygonCommutativity : public Law<PolygonCommutativity<Type>, LOKI_TYPELIST_2(Type,Type), LOKI_TYPELIST_2(Type,Type)> { // a o b == b o a . . . bool holds() { using namespace boost::polygon; using namespace boost::polygon::operators; Type value_a = this->template getInputValue<operand_a>(); Type value_b = this->template getInputValue<operand_b>(); Type left = value_a; left += value_b; // Compiler fails to find the appropriate overload // but // this works self_assignment_boolean_op<Type,Type,0>(left, value_b); // and also this works boost::polygon::operators::operator+=<Type,Type>(left, value_b); // and this boost::polygon::operators::operator+=(left, value_b); . . . return equivalence(left, right); } }; ----------------------------------------------------------- moreover, if my custom PolygonSet conainer implements an operator += this operator is *silently* chosen by the compiler, so the wrong addition function is called! Contrary to the traditional understanding of a concept, that defines *requirements* for a parameter class it can use, we have to take care here, that the client class *does not* implement certain operations. I am afraid this is not a good thing. I hope this is fixable, may be the error is on my side but I can't see it yet. Regards Joachim

Joachim Faulhaber wrote:
Hi Luke and polygonists,
trying to set up some law based tests for boost::polygon I faced difficulties with the overload resolution of operators under msvc-9.
moreover, if my custom PolygonSet conainer implements an operator += this operator is *silently* chosen by the compiler, so the wrong addition function is called!
Contrary to the traditional understanding of a concept, that defines *requirements* for a parameter class it can use, we have to take care here, that the client class *does not* implement certain operations. I am afraid this is not a good thing.
I hope this is fixable, may be the error is on my side but I can't see it yet.
Joachim, How is your interval container library coming along? It was pointed out by one of the reviewer that my interval concept was lacking an interval set concept, which made me think of you and your work. If I have a generic function with a given name and a function of the same name exists that accepts your type explicitly the compiler will prefer the better match. I have to give my functions names, and I prefer to give them simple and intuitive names. This increases the odds that there is a name collision. The namespace helps, but operator syntax doesn't benefit. If your type has operators defined for it that conflict with my operators you will have to qualify your calls to my operators with the namespace, which is unfortunate, but the concept system itself is not broken by this, just the convenience of calling the operator functions. Thanks for taking the time to look at my library, what you are doing with loki looks very interesting, Luke

2009/9/1 Simonson, Lucanus J <lucanus.j.simonson@intel.com>:
How is your interval container library coming along? It was pointed out by one of the reviewer that my interval concept was lacking an interval set concept, which made me think of you and your work.
Thanks for your interest. I'm planning to submit for review within a few days.
If I have a generic function with a given name and a function of the same name exists that accepts your type explicitly the compiler will prefer the better match. I have to give my functions names, and I prefer to give them simple and intuitive names. This increases the odds that there is a name collision. The namespace helps, but operator syntax doesn't benefit.
If your type has operators defined for it that conflict with my operators you will have to qualify your calls to my operators with the namespace
(1) What is troublesome here is, that the better matching but semantically false operator is *silently* chosen. If a user uses boost::polygon which some thirdparty::polygon_sequence, which happens to implement operator +=, which is not unnatural for a sequence type, she will innocently and unconsciously produce false code using both components right. It may even happen, that the thirdparty::polygon_sequence::operator+= does the right thing most of the time, and only fails in special circumstances. I do not attribute this problem to your design. It's more a deficiency of the language. c++0x concepts (that we unfortunately won't get) would be helpful. Nevertheless, I think this is a problem we should be aware of. At least it should be mentioned in the docs in a section that refers to requirements on client types used with boost::polygon. (2) But this was only one of two problems I had. After removing operator+= from the custom type, the compiler still did not resolve the call of += to the intended instantiation from boost::polygon. This is unfortunate, because a whole suite of Laws in my law based tester can not be used out of the box, since the Law's implementations are exploiting the syntactical equality of operators (without namespace qualification). In contrast to point (1) I can not see why the compiler refueses to use your unqualified operators in this case.
Thanks for taking the time to look at my library, what you are doing with loki looks very interesting, Luke
Thanks for contribution this work Joachim
participants (2)
-
Joachim Faulhaber
-
Simonson, Lucanus J