opengl and boost::function casting problems. .
here is the basic header file basicgl.hpp #include <windows.h> #include <GL/gl.h> #include <GL/glu.h> #include <GL/glut.h> #include <boost/function.hpp> #include <boost/static_assert.hpp> #include <boost/type_traits.hpp> #include <boost/cast.hpp> template <class T> boost::function<void*(const T&, const T&)> getVerxFunc2() { BOOST_STATIC_ASSERT(boost::is_integral<T>::value || boost::is_floating_point<T>::value); return (boost::is_floating_point<T>::value) ? &glVertex2d : &glVertex2i; } template <class T> boost::function<void*(const T&, const T&, const T&)> getVerxFunc3() { BOOST_STATIC_ASSERT(boost::is_integral<T>::value || boost::is_floating_point<T>::value); return (boost::is_integral<T>::value) ? &glVertex3i : &glVertex3d; } template <class T> void drawDot(const T& x, const T& y) { boost::function<void(const T&, const T&)> myFunc(getVerxFunc2<T>()); glBegin(GL_POINTS); myFunc(x, y); glEnd(); glFlush(); } template <class T> void drawDot(const T& x, const T& y, const T& z) { boost::function<void(const T&, const T&, const T&)> myFunc(getVerxFunc3<T>()); glBegin(GL_POINTS); myFunc(x, y, z); glEnd(); glFlush(); } template <class T> void drawLine(const T& x1, const T& y1, const T& x2, const T& y2) { boost::function<void(const T&, const T&)> myFunc(getVerxFunc2<T>()); glBegin(GL_LINE); myFunc(x1, y1); myFunc(x2, y2); glEnd(); glFlush(); } template <class T> void drawLine(const T& x1, const T& y1, const T& x2, const T& y2, const T& z1, const T& z2) { boost::function<void(const T&, const T&, const T&)> myFunc(getVerxFunc3<T>()); glBegin(GL_LINE); myFunc(x1, y1, z1); myFunc(x2, y2, z2); glEnd(); glFlush(); } drawLine(4.1, 5.2, 3.9, 4.2); When i compile i get the following errors. 16 D:\Data\cs classes\cs450\c++\BasicGL.hpp conditional expression between distinct pointer types `void (*)(GLdouble, GLdouble)' and `void (*)(GLint, GLint)' lacks a cast 46 D:\Data\cs classes\cs450\c++\BasicGL.hpp instantiated from `void drawLine(const T&, const T&, const T&, const T&) [with T = GLdouble]' 16 D:\Data\cs classes\cs450\c++\BasicGL.hpp invalid conversion from `void (*)(GLdouble, GLdouble)' to `void*' 16 D:\Data\cs classes\cs450\c++\BasicGL.hpp invalid conversion from `void (*)(GLint, GLint)' to `void*' 85 D:\Data\Devcpp\include\boost_1_33_1\boost\function\function_template.hpp ISO C++ forbids casting between pointer-to-function and pointer-to-object Is there a nice work around this? Thanks.
chun ping wang wrote:
Is there a nice work around this?
Yes: if(boost::is_floating_point<T>::value) return &glVertex2d; else return &glVertex2i; and the same goes for the other ternary. This has nothing to do with boost. The two options in a ternary have to be of the same type. You could also cast them, but that would only be shorter with appropriate typedefs. Jens
On Mon, 21 Aug 2006, chun ping wang wrote: [...]
template <class T> boost::function<void*(const T&, const T&, const T&)> getVerxFunc3() { BOOST_STATIC_ASSERT(boost::is_integral<T>::value || boost::is_floating_point<T>::value); return (boost::is_integral<T>::value) ? &glVertex3i : &glVertex3d; }
[...]
template <class T> void drawDot(const T& x, const T& y, const T& z) { boost::function<void(const T&, const T&, const T&)> myFunc(getVerxFunc3<T>()); glBegin(GL_POINTS); myFunc(x, y, z); glEnd(); glFlush(); }
[just kept one example from the above] Isn't using boost::function overkill here? I would rather do this: template < typename T > void gl_vertex( const T& x , const T& y , const T& z ) { // you can use the BOOST_STATIC_ASSERT as above here, or use // boost::enable_if with the same condition around the void return if ( boost::is_floating_point< T >::value ) { glVertex3d( x , y , z ) ; } else { glVertex3i( x , y , z ) ; } } or even simply this: void gl_vertex( GLdouble x , GLdouble y , GLdouble z ) { glVertex3d( x , y , z ) ; } void gl_vertex( GLint x , GLint y , GLint z ) { glVertex3i( x , y , z ) ; } and then: template < typename T > void drawDot( const T& x , const T& y , const T& z ) { glBegin( GL_POINTS ) ; gl_vertex( x , y , z ) ; glEnd() ; } That should be more efficient and, especially for the second case, is a simpler to read overall. Anyway, just my two cents. -- François Duranleau LIGUM, Université de Montréal "Sacrifices are a necessary factor in creating a new destiny. A small misfortune becomes the cornerstone of a greater happiness." - Emperor Dornkirk, in _The Vision of Escaflowne_ _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
Hi, sorry for another problem... i have a simple question to ask... lets say say i have base class struct GeomObject { // draws an wire shape virtual void drawAbstract(const GLfloat& x, const GLfloat& y, const GLfloat& z) = 0; // draws a solid shape. virtual void drawSolid(const GLfloat& x, const GLfloat& y, const GLfloat& z) = 0; } Now i have bunch of stuff that inherits it.. Like class Circle, class Sphere, class Cylinder, class Cone and all of them implement drawSolid and drawAbstract (radius base assumed). I have a function call drawCircle(const std::string& r, (someBoostFunctionParam)) { Circle cir(4.0, r); // construct a circle with radius 4.0 and name r cir.someBoostFunctionParam(x, y, z); } thus if i say drawCircle("solid", &Circle::drawSolid); drawCircle("abstract", &Circle::drawAbstract); How do you do that? Or whats the best way to do it. On 8/22/06, François Duranleau <duranlef@iro.umontreal.ca> wrote:
On Mon, 21 Aug 2006, chun ping wang wrote:
[...]
template <class T> boost::function<void*(const T&, const T&, const T&)> getVerxFunc3() { BOOST_STATIC_ASSERT(boost::is_integral<T>::value || boost::is_floating_point<T>::value); return (boost::is_integral<T>::value) ? &glVertex3i : &glVertex3d; }
[...]
template <class T> void drawDot(const T& x, const T& y, const T& z) { boost::function<void(const T&, const T&, const T&)> myFunc(getVerxFunc3<T>()); glBegin(GL_POINTS); myFunc(x, y, z); glEnd(); glFlush(); }
[just kept one example from the above]
Isn't using boost::function overkill here? I would rather do this:
template < typename T > void gl_vertex( const T& x , const T& y , const T& z ) { // you can use the BOOST_STATIC_ASSERT as above here, or use // boost::enable_if with the same condition around the void return
if ( boost::is_floating_point< T >::value ) { glVertex3d( x , y , z ) ; } else { glVertex3i( x , y , z ) ; } }
or even simply this:
void gl_vertex( GLdouble x , GLdouble y , GLdouble z ) { glVertex3d( x , y , z ) ; }
void gl_vertex( GLint x , GLint y , GLint z ) { glVertex3i( x , y , z ) ; }
and then:
template < typename T > void drawDot( const T& x , const T& y , const T& z ) { glBegin( GL_POINTS ) ; gl_vertex( x , y , z ) ; glEnd() ; }
That should be more efficient and, especially for the second case, is a simpler to read overall.
Anyway, just my two cents.
-- François Duranleau LIGUM, Université de Montréal
"Sacrifices are a necessary factor in creating a new destiny. A small misfortune becomes the cornerstone of a greater happiness." - Emperor Dornkirk, in _The Vision of Escaflowne_
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
participants (3)
-
chun ping wang
-
François Duranleau
-
Jens Theisen