Re: [boost] [Polygon] What does this error mean?

Dear Luke (& others), Here's some test code, followed by the errors that I get when I try to compile it. It boils down to some confusion about whether set is a type or a function. Am I doing something that isn't allowed? Thanks for any suggestions. #include <boost/polygon/polygon.hpp> template<typename COORD_T> struct Box { typedef COORD_T coord_t; coord_t x0; coord_t y0; coord_t x1; coord_t y1; }; typedef int screen_coord_t; typedef Box<screen_coord_t> screen_box_t; namespace boost { namespace polygon { template <> struct geometry_concept<screen_box_t> { typedef rectangle_concept type; }; template <> struct rectangle_traits<screen_box_t> { typedef screen_coord_t coordinate_type; typedef std::pair<screen_coord_t,screen_coord_t> interval_type; static inline interval_type get(const screen_box_t& rectangle, orientation_2d orient) { return (orient==HORIZONTAL) ? std::make_pair(rectangle.x0,rectangle.x1) : std::make_pair(rectangle.y0,rectangle.y1); } }; }; }; typedef boost::polygon::polygon_90_set_data<screen_coord_t> markers_t; markers_t markers; void draw_marker(screen_box_t sb) { using namespace boost::polygon::operators; markers |= sb; } /usr/lib/gcc/i486-linux-gnu/4.1.2/../../../../include/c++/4.1.2/bits/stl_set.h: In function ‘typename boost::enable_if<typename boost::polygon::gtl_and_3<boost::polygon::y_r_assign, typename boost::polygon::is_mutable_rectangle_concept<typename boost::polygon::geometry_concept<T>::type>::type, typename boost::polygon::is_rectangle_concept<typename boost::polygon::geometry_concept<T2>::type>::type>::type, rectangle_type_1>::type& boost::polygon::assign(rectangle_type_1&, const rectangle_type_2&) [with rectangle_type_1 = boost::polygon::rectangle_data<int>, rectangle_type_2 = Box<int>]’: /usr/local/src/gtl/boost/polygon/detail/iterator_geometry_to_set.hpp:34: instantiated from ‘boost::polygon::iterator_geometry_to_set<boost::polygon::rectangle_concept, rectangle_type>::iterator_geometry_to_set(const rectangle_type&, boost::polygon::direction_1d, boost::polygon::orientation_2d, bool) [with rectangle_type = Box<int>]’ /usr/local/src/gtl/boost/polygon/polygon_90_set_data.hpp:137: instantiated from ‘void boost::polygon::polygon_90_set_data<T>::insert(const geometry_type&, bool, boost::polygon::orientation_2d) [with geometry_type = Box<int>, T = int]’ /usr/local/src/gtl/boost/polygon/polygon_90_set_data.hpp:113: instantiated from ‘void boost::polygon::polygon_90_set_data<T>::insert(iT, iT, boost::polygon::orientation_2d) [with iT = const Box<int>*, T = int]’ /usr/local/src/gtl/boost/polygon/detail/polygon_90_set_view.hpp:318: instantiated from ‘typename boost::enable_if<typename boost::polygon::gtl_and<boost::polygon::operators::y_ps90_pe, typename boost::polygon::is_polygon_90_set_type<polygon_set_type_2>::type>::type, boost::polygon::polygon_90_set_data<coordinate_type> >::type& boost::polygon::operators::operator+=(boost::polygon::polygon_90_set_data<coordinate_type>&, const geometry_type_2&) [with coordinate_type_1 = int, geometry_type_2 = Box<int>]’ /usr/local/src/gtl/boost/polygon/detail/polygon_90_set_view.hpp:329: instantiated from ‘typename boost::enable_if<typename boost::polygon::gtl_and<boost::polygon::operators::y_ps90_be, typename boost::polygon::is_polygon_90_set_type<polygon_set_type_2>::type>::type, boost::polygon::polygon_90_set_data<coordinate_type> >::type& boost::polygon::operators::operator|=(boost::polygon::polygon_90_set_data<coordinate_type>&, const geometry_type_2&) [with coordinate_type_1 = int, geometry_type_2 = screen_box_t]’ testpoly.cc:41: instantiated from here /usr/lib/gcc/i486-linux-gnu/4.1.2/../../../../include/c++/4.1.2/bits/stl_set.h:71: error: ‘template<class _Key, class _Compare, class _Alloc> class std::set’ is not a function, /usr/local/src/gtl/boost/polygon/point_concept.hpp:77: error: conflict with ‘template<class T, class coordinate_type> void boost::polygon::set(T&, boost::polygon::orientation_2d, coordinate_type, typename boost::enable_if<typename boost::polygon::is_mutable_point_concept<typename boost::polygon::geometry_concept<T>::type>::type, void>::type*)’ /usr/local/src/gtl/boost/polygon/rectangle_concept.hpp:192: error: in call to ‘set’ /usr/local/src/gtl/boost/polygon/detail/iterator_geometry_to_set.hpp:34: instantiated from ‘boost::polygon::iterator_geometry_to_set<boost::polygon::rectangle_concept, rectangle_type>::iterator_geometry_to_set(const rectangle_type&, boost::polygon::direction_1d, boost::polygon::orientation_2d, bool) [with rectangle_type = Box<int>]’ /usr/local/src/gtl/boost/polygon/polygon_90_set_data.hpp:137: instantiated from ‘void boost::polygon::polygon_90_set_data<T>::insert(const geometry_type&, bool, boost::polygon::orientation_2d) [with geometry_type = Box<int>, T = int]’ /usr/local/src/gtl/boost/polygon/polygon_90_set_data.hpp:113: instantiated from ‘void boost::polygon::polygon_90_set_data<T>::insert(iT, iT, boost::polygon::orientation_2d) [with iT = const Box<int>*, T = int]’ /usr/local/src/gtl/boost/polygon/detail/polygon_90_set_view.hpp:318: instantiated from ‘typename boost::enable_if<typename boost::polygon::gtl_and<boost::polygon::operators::y_ps90_pe, typename boost::polygon::is_polygon_90_set_type<polygon_set_type_2>::type>::type, boost::polygon::polygon_90_set_data<coordinate_type> >::type& boost::polygon::operators::operator+=(boost::polygon::polygon_90_set_data<coordinate_type>&, const geometry_type_2&) [with coordinate_type_1 = int, geometry_type_2 = Box<int>]’ /usr/local/src/gtl/boost/polygon/detail/polygon_90_set_view.hpp:329: instantiated from ‘typename boost::enable_if<typename boost::polygon::gtl_and<boost::polygon::operators::y_ps90_be, typename boost::polygon::is_polygon_90_set_type<polygon_set_type_2>::type>::type, boost::polygon::polygon_90_set_data<coordinate_type> >::type& boost::polygon::operators::operator|=(boost::polygon::polygon_90_set_data<coordinate_type>&, const geometry_type_2&) [with coordinate_type_1 = int, geometry_type_2 = screen_box_t]’ testpoly.cc:41: instantiated from here /usr/local/src/gtl/boost/polygon/rectangle_concept.hpp:192: error: no matching function for call to ‘set(boost::polygon::rectangle_data<int>&, boost::polygon::orientation_2d_enum, std::pair<int, int>)’ /usr/local/src/gtl/boost/polygon/detail/iterator_geometry_to_set.hpp:34: instantiated from ‘boost::polygon::iterator_geometry_to_set<boost::polygon::rectangle_concept, rectangle_type>::iterator_geometry_to_set(const rectangle_type&, boost::polygon::direction_1d, boost::polygon::orientation_2d, bool) [with rectangle_type = Box<int>]’ /usr/local/src/gtl/boost/polygon/polygon_90_set_data.hpp:137: instantiated from ‘void boost::polygon::polygon_90_set_data<T>::insert(const geometry_type&, bool, boost::polygon::orientation_2d) [with geometry_type = Box<int>, T = int]’ /usr/local/src/gtl/boost/polygon/polygon_90_set_data.hpp:113: instantiated from ‘void boost::polygon::polygon_90_set_data<T>::insert(iT, iT, boost::polygon::orientation_2d) [with iT = const Box<int>*, T = int]’ /usr/local/src/gtl/boost/polygon/detail/polygon_90_set_view.hpp:318: instantiated from ‘typename boost::enable_if<typename boost::polygon::gtl_and<boost::polygon::operators::y_ps90_pe, typename boost::polygon::is_polygon_90_set_type<polygon_set_type_2>::type>::type, boost::polygon::polygon_90_set_data<coordinate_type> >::type& boost::polygon::operators::operator+=(boost::polygon::polygon_90_set_data<coordinate_type>&, const geometry_type_2&) [with coordinate_type_1 = int, geometry_type_2 = Box<int>]’ /usr/local/src/gtl/boost/polygon/detail/polygon_90_set_view.hpp:329: instantiated from ‘typename boost::enable_if<typename boost::polygon::gtl_and<boost::polygon::operators::y_ps90_be, typename boost::polygon::is_polygon_90_set_type<polygon_set_type_2>::type>::type, boost::polygon::polygon_90_set_data<coordinate_type> >::type& boost::polygon::operators::operator|=(boost::polygon::polygon_90_set_data<coordinate_type>&, const geometry_type_2&) [with coordinate_type_1 = int, geometry_type_2 = screen_box_t]’ testpoly.cc:41: instantiated from here /usr/lib/gcc/i486-linux-gnu/4.1.2/../../../../include/c++/4.1.2/bits/stl_set.h:71: error: ‘template<class _Key, class _Compare, class _Alloc> class std::set’ is not a function, /usr/local/src/gtl/boost/polygon/point_concept.hpp:77: error: conflict with ‘template<class T, class coordinate_type> void boost::polygon::set(T&, boost::polygon::orientation_2d, coordinate_type, typename boost::enable_if<typename boost::polygon::is_mutable_point_concept<typename boost::polygon::geometry_concept<T>::type>::type, void>::type*)’ /usr/local/src/gtl/boost/polygon/rectangle_concept.hpp:193: error: in call to ‘set’ /usr/local/src/gtl/boost/polygon/rectangle_concept.hpp:193: error: no matching function for call to ‘set(boost::polygon::rectangle_data<int>&, boost::polygon::orientation_2d_enum, std::pair<int, int>)’

Phil Endecott wrote:
Dear Luke (& others),
Here's some test code, followed by the errors that I get when I try to compile it. It boils down to some confusion about whether set is a type or a function. Am I doing something that isn't allowed? Thanks for any suggestions.
template <> struct rectangle_traits<screen_box_t> { typedef screen_coord_t coordinate_type; typedef std::pair<screen_coord_t,screen_coord_t> interval_type; static inline interval_type get(const screen_box_t& rectangle, orientation_2d orient) { return (orient==HORIZONTAL) ? std::make_pair(rectangle.x0,rectangle.x1) : std::make_pair(rectangle.y0,rectangle.y1); } }; }; };
Phil, I boils down to the fact that you are using std::pair<int, int> for your interval return type in get() in the screen_box_t traits, but did not register it as a type of interval concept or define traits for it. If you set up the interval_traits for std::pair and register it with a specialization of geometry_concept for interval_concept you should be fine. It states in the docs that while pair or tuple can be made concepts of point or interval, I don't do that for you because I can't make them simultaneously point and interval. If you later set up point_traits for std::pair somewhere else you will get a raft of ambiguous overload errors because both point and interval interfaces will match your type. Thanks, Luke

Simonson, Lucanus J wrote:
I boils down to the fact that you are using std::pair<int, int> for your interval return type in get() in the screen_box_t traits, but did not register it as a type of interval concept or define traits for it. If you set up the interval_traits for std::pair and register it with a specialization of geometry_concept for interval_concept you should be fine.
I've added this: template <> struct geometry_concept< std::pair<screen_coord_t,screen_coord_t> > { typedef interval_concept type; }; template <> struct interval_traits< std::pair<screen_coord_t,screen_coord_t> > { typedef screen_coord_t coordinate_type; static inline coordinate_type get(const std::pair<screen_coord_t,screen_coord_t>& interval, direction_1d dir) { return (dir==LOW) ? interval.first : interval.second; } }; and I seem to be getting much the same error. Any ideas? Phil.

Phil Endecott wrote:
Simonson, Lucanus J wrote:
I boils down to the fact that you are using std::pair<int, int> for your interval return type in get() in the screen_box_t traits, but did not register it as a type of interval concept or define traits for it. If you set up the interval_traits for std::pair and register it with a specialization of geometry_concept for interval_concept you should be fine.
I've added this:
template <> struct geometry_concept< std::pair<screen_coord_t,screen_coord_t> > { typedef interval_concept type; };
template <> struct interval_traits< std::pair<screen_coord_t,screen_coord_t> > { typedef screen_coord_t coordinate_type; static inline coordinate_type get(const std::pair<screen_coord_t,screen_coord_t>& interval, direction_1d dir) { return (dir==LOW) ? interval.first : interval.second; } };
and I seem to be getting much the same error.
Any ideas?
The error the above should fix is: /usr/local/src/gtl/boost/polygon/rectangle_concept.hpp:192: error: no matching function for call to 'set(boost::polygon::rectangle_data<int>&, boost::polygon::orientation_2d_enum, std::pair<int, int>)' Is that error still present? Try using the rectangle and interval concepts for simple things like accessing their coordinate values to get more straightforward errors. Once you have interval and rectangle setup it should work just like the point and polygon examples. Luke

Simonson, Lucanus J wrot:
The error the above should fix is:
/usr/local/src/gtl/boost/polygon/rectangle_concept.hpp:192: error: no matching function for call to 'set(boost::polygon::rectangle_data<int>&, boost::polygon::orientation_2d_enum, std::pair<int, int>)'
Is that error still present?
Ha, actually I hadn't noticed that particular error amongst the kilobytes of other spewage. It has now gone. What I am still getting is the "class std::set is not a function" stuff. I've also added the interval_mutable_traits specialisation that Thomas suggested without any improvement. The code that I'm still unable to compile is at http://chezphil.org/tmp/testpoly.cc - if anyone can work out what I've done wrong, please let me know! I would be interested to hear if anyone thinks that concept checking could make these particular errors any more readable. Regards, Phil.

Phil Endecott wrote:
The code that I'm still unable to compile is at http://chezphil.org/tmp/testpoly.cc - if anyone can work out what I've done wrong, please let me know!
changing line 192, 193 of the file rectangle_concept.hpp from set(lvalue, HORIZONTAL, get(rvalue, HORIZONTAL)); set(lvalue, VERTICAL, get(rvalue, VERTICAL)); to boost::polygon::set(lvalue, HORIZONTAL, get(rvalue, HORIZONTAL)); boost::polygon::set(lvalue, VERTICAL, get(rvalue, VERTICAL)); solves the problem for me. I'm no ADL expert (ADL=argument dependent lookup), but I guess the std::pair returned by get for your custom rectangle type pulls in the std namespace, so that the name conflict with std::set occurs. Fully qualifying the calls as I proposed is the correct solution for such ADL problems, IIRC. Regards, Thomas

Thomas Klimpel wrote:
Fully qualifying the calls as I proposed is the correct solution for such ADL problems, IIRC.
Even if the above statement should be true, my proposed fix still had a potential ADL issue. I guess ::boost::polygon::set(lvalue, HORIZONTAL, get(rvalue, HORIZONTAL)); ::boost::polygon::set(lvalue, VERTICAL, get(rvalue, VERTICAL)); is the correct fix, but check with an ADL expert to be sure. Regards, Thomas

AMDG Thomas Klimpel wrote:
Thomas Klimpel wrote:
Fully qualifying the calls as I proposed is the correct solution for such ADL problems, IIRC.
Even if the above statement should be true, my proposed fix still had a potential ADL issue. I guess
::boost::polygon::set(lvalue, HORIZONTAL, get(rvalue, HORIZONTAL)); ::boost::polygon::set(lvalue, VERTICAL, get(rvalue, VERTICAL));
is the correct fix, but check with an ADL expert to be sure.
Any qualification suppresses ADL. You don't need full qualification. In Christ, Steven Watanabe

Steven Watanabe wrote:
AMDG
Thomas Klimpel wrote:
Thomas Klimpel wrote:
Fully qualifying the calls as I proposed is the correct solution for such ADL problems, IIRC.
Even if the above statement should be true, my proposed fix still had a potential ADL issue. I guess
::boost::polygon::set(lvalue, HORIZONTAL, get(rvalue, HORIZONTAL)); ::boost::polygon::set(lvalue, VERTICAL, get(rvalue, VERTICAL));
is the correct fix, but check with an ADL expert to be sure.
Any qualification suppresses ADL. You don't need full qualification.
FWIW, so does wrapping the function name into parenthesis, as in: (set)(lvalue, HORIZONTAL, get(rvalue, HORIZONTAL)); (set)(lvalue, VERTICAL, get(rvalue, VERTICAL)); I just pointed it out as that technique can be more usable than qualification. Best -- Fernando Cacciola SciSoft Consulting, Founder http://www.scisoft-consulting.com

Phil Endecott wrote:
Simonson, Lucanus J wrot:
The error the above should fix is:
/usr/local/src/gtl/boost/polygon/rectangle_concept.hpp:192: error: no matching function for call to 'set(boost::polygon::rectangle_data<int>&, boost::polygon::orientation_2d_enum, std::pair<int, int>)'
Is that error still present?
Ha, actually I hadn't noticed that particular error amongst the kilobytes of other spewage. It has now gone. What I am still getting is the "class std::set is not a function" stuff.
I've also added the interval_mutable_traits specialisation that Thomas suggested without any improvement.
I would be interested to hear if anyone thinks that concept checking could make these particular errors any more readable.
Concept checking would help immensely -- and was what I thought of immediately upon seeing Lucanus' reply to your initial query -- because it would have indicated that std::pair<int,int> was not an interval type. The documentation would then be able to direct you to the traits specializations needed to satisfy the failed concept. That is so much more helpful than obscure diagnostics from deep within the library. _____ Rob Stewart robert.stewart@sig.com Software Engineer, Core Software using std::disclaimer; Susquehanna International Group, LLP http://www.sig.com IMPORTANT: The information contained in this email and/or its attachments is confidential. If you are not the intended recipient, please notify the sender immediately by reply and immediately delete this message and all its attachments. Any review, use, reproduction, disclosure or dissemination of this message or any attachment by an unintended recipient is strictly prohibited. Neither this message nor any attachment is intended as or should be construed as an offer, solicitation or recommendation to buy or sell any security or other financial instrument. Neither the sender, his or her employer nor any of their respective affiliates makes any warranties as to the completeness or accuracy of any of the information contained herein or that this message or any of its attachments is free of viruses.

Stewart, Robert wrote:
Phil Endecott wrote:
Simonson, Lucanus J wrot:
The error the above should fix is:
/usr/local/src/gtl/boost/polygon/rectangle_concept.hpp:192: error: no matching function for call to 'set(boost::polygon::rectangle_data<int>&, boost::polygon::orientation_2d_enum, std::pair<int, int>)'
Is that error still present?
Ha, actually I hadn't noticed that particular error amongst the kilobytes of other spewage. It has now gone. What I am still getting is the "class std::set is not a function" stuff.
I've also added the interval_mutable_traits specialisation that Thomas suggested without any improvement.
I would be interested to hear if anyone thinks that concept checking could make these particular errors any more readable.
Concept checking would help immensely -- and was what I thought of immediately upon seeing Lucanus' reply to your initial query -- because it would have indicated that std::pair<int,int> was not an interval type. The documentation would then be able to direct you to the traits specializations needed to satisfy the failed concept. That is so much more helpful than obscure diagnostics from deep within the library.
If the rectangle concept applied a concept check on the interval_type defined in its traits and we checked the rectangle concept at the interface Phil originally called we would indeed get the error sooner and it could provide a better description of what was wrong. I think that it might be handy to provide some concept compile time checks that the user can use to verify that their traits are setup correctly. It might be overkill to perform concept checking on every interface, however. A simple check is to call the few free functions that directly access the traits. If these succeed all other interfaces will be valid. This issue with ADL and set() is something I've seen before. When I first used std::vector and std::list as models for polygon_concept and polygon_set_concept I ran into it and resolved the problems. Thanks, Luke

Simonson, Lucanus J
Stewart, Robert wrote:
Concept checking would help immensely -- and was what I thought of immediately upon seeing Lucanus' reply to your initial query -- because it would have indicated that std::pair<int,int> was not an interval type. The documentation would then be able to direct you to the traits specializations needed to satisfy the failed concept. That is so much more helpful than obscure diagnostics from deep within the library.
If the rectangle concept applied a concept check on the interval_type defined in its traits and we checked the rectangle concept at the interface Phil originally called we would indeed get the error sooner and it could provide a better description of what was wrong.
I think that it might be handy to provide some concept compile time checks that the user can use to verify that their traits are setup correctly. It might be overkill to perform concept checking on every interface, however. A simple check is to call the few free functions that directly access the traits. If these succeed all other interfaces will be valid.
Each public API that accepts an Interval should assert that the type meets the interval concept. _____ Rob Stewart robert.stewart@sig.com Software Engineer, Core Software using std::disclaimer; Susquehanna International Group, LLP http://www.sig.com IMPORTANT: The information contained in this email and/or its attachments is confidential. If you are not the intended recipient, please notify the sender immediately by reply and immediately delete this message and all its attachments. Any review, use, reproduction, disclosure or dissemination of this message or any attachment by an unintended recipient is strictly prohibited. Neither this message nor any attachment is intended as or should be construed as an offer, solicitation or recommendation to buy or sell any security or other financial instrument. Neither the sender, his or her employer nor any of their respective affiliates makes any warranties as to the completeness or accuracy of any of the information contained herein or that this message or any of its attachments is free of viruses.

Phil Endecott wrote:
I've added this: ... and I seem to be getting much the same error.
How about also adding template <> struct interval_mutable_traits< std::pair<screen_coord_t,screen_coord_t> > { static inline void set(std::pair<screen_coord_t,screen_coord_t>& interval, direction_1d dir, screen_coord_t value) { if (dir==LOW) interval.first = value; else interval.second = value; } static inline std::pair<screen_coord_t,screen_coord_t> construct(screen_coord_t low_value, screen_coord_t high_value) { return std::pair<screen_coord_t,screen_coord_t> (low_value, high_value); } }; ???
participants (6)
-
Fernando Cacciola
-
Phil Endecott
-
Simonson, Lucanus J
-
Steven Watanabe
-
Stewart, Robert
-
Thomas Klimpel