[bind/lambda] Matching signature constness?

Here's a bit of code (and my apologies for it's length, but I'm unsure which bit is the failure point) #include <cstddef> #include "boost/lambda/lambda.hpp" #include "boost/lambda/bind.hpp" #include "boost/function.hpp" #include "boost/type_traits.hpp" namespace { template < bool > struct cmp_detail { template < typename T > static bool cmp( const T & lhs, const T & rhs ) { return lhs != rhs; } }; template < > struct cmp_detail< true > { template < typename T, std :: size_t sz > static bool cmp( const T ( & lhs )[ sz ], const T ( & rhs )[ sz ] ) { using boost :: lambda :: _1; using boost :: lambda :: bind; using boost :: lambda :: var; boost :: function< bool( unsigned ) > cmp_element = bind( cmp_detail< boost :: is_array< T > :: value > :: cmp, var( lhs )[ _1 ], var( rhs )[ _1 ] ); for ( unsigned i = 0; i != sz; ++ i ) if ( cmp_element( i ) ) // if ( cmp_detail< boost :: is_array< T > :: value > :: cmp( lhs[ i ], rhs[ i ] ) ) return true; return false; } }; template < typename T > bool cmp( const T & lhs, const T & rhs ) { return cmp_detail< boost :: is_array< T > :: value > :: cmp( lhs, rhs ); } template < typename T, std :: size_t sz > struct Block { typedef T type[ sz ][ sz ]; }; } int main( ) { Block< int, 16 > :: type a; Block< int, 16 > :: type b; cmp( a, b ); } The problem is the bind call in cmp_detail<true>::cmp(...). Error is this block.cpp: In static member function `static bool <unnamed>::cmp_detail< true>::cmp(const T (&)[sz], const T (&)[sz]) [w ith T = int[16], unsigned int sz = 16u]': block.cpp:45: instantiated from `bool <unnamed>::cmp(const T&, const T&) [with T = int[16][16]]' block.cpp:61: instantiated from here block.cpp:32: error: no matching function for call to `bind(<unknown type>, const boost::lambda::lambda_functor<boost::l ambda::lambda_functor_base<boost::lambda::other_action<boost::lambda::subscript_action>, boost::tuples::tuple<boost::lam bda::lambda_functor<boost::lambda::identity<const int (&)[16][16]> >, boost::lambda::lambda_functor<boost::lambda::place holder<1> >, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boo st::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type> > >, const boost::l ambda::lambda_functor<boost::lambda::lambda_functor_base<boost::lambda::other_action<boost::lambda::subscript_action>, b oost::tuples::tuple<boost::lambda::lambda_functor<boost::lambda::identity<const int (&)[16][16]> >, boost::lambda::lambd a_functor<boost::lambda::placeholder<1> >, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples:: null_type> > >)' I think perhaps the var() calls are not preserving constness quite right? Any help would be welcome. Thanks. - Rob.

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On Wednesday 10 December 2008 07:55 am, Robert Jones wrote:
template < typename T, std :: size_t sz > static bool cmp( const T ( & lhs )[ sz ], const T ( & rhs )[ sz ] ) { using boost :: lambda :: _1; using boost :: lambda :: bind; using boost :: lambda :: var;
boost :: function< bool( unsigned ) > cmp_element = bind( cmp_detail< boost :: is_array< T > :: value > :: cmp, var( lhs )[ _1 ], var( rhs )[ _1 ] );
For one thing, you are trying to bind a template member function without specifying its template parameters (you only specified the template parameter of the class, not the method which is also a template), which you can't do.
block.cpp:32: error: no matching function for call to `bind(<unknown type>, -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux)
iD8DBQFJP9RL5vihyNWuA4URAkf3AJ4x5bpR87hiDD8dRVJdwqOc6mWHSwCggUaq T3l3AZqpimNGhYzpqR6bsQs= =+bkb -----END PGP SIGNATURE-----

On Wed, Dec 10, 2008 at 2:37 PM, Frank Mori Hess <frank.hess@nist.gov>wrote: Thanks for that Frank - that just shows the perils of not posting the exact code which is causing problems! I have fabricated a much shorter example which exhibits the same issue for me... #include <cstddef> #include "boost/lambda/lambda.hpp" #include "boost/lambda/bind.hpp" #include "boost/function.hpp" template < typename T > bool is_zero( const T & t ) { return t == 0; } template < typename T, std :: size_t sz > bool first_element_equal_zero( const T ( & array )[ sz ] ) { using namespace boost; using lambda :: bind; using lambda :: _1; using lambda :: constant_ref; function< const T &( unsigned ) > element = constant_ref( array )[ _1 ]; function< bool( unsigned ) > e = bind( is_zero< T >, element( _1 ) ); return e( 0 ); } int main( ) { int a[ 10 ]; first_element_equal_zero( a ); } $ g++ -c element.cpp element.cpp: In function `bool first_element_equal_zero(const T (&)[sz]) [with T = int, unsigned int sz = 10u]': element.cpp:30: instantiated from here element.cpp:21: error: no match for call to `(boost::function<const int&()(unsigned int)>) (const boost::lambda::lambda_ functor<boost::lambda::placeholder<1> >&)' /usr/include/boost/function/function_template.hpp:810: note: candidates are: typename boost::function1<R, T0>::result_ty pe boost::function1<R, T0>::operator()(T0) const [with R = const int&, T0 = unsigned int] Which still evades my comprehension! I'd appreciate some guidance here. Thanks. - Rob.

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On Wednesday 10 December 2008 10:41 am, Robert Jones wrote:
function< bool( unsigned ) > e = bind( is_zero< T >, element( _1 ) );
I think you wanted to do a nested bind (and you're missing an address-of operator): function< bool( unsigned ) > e = bind( &is_zero< T >, bind( element, _1 ) );
element.cpp:21: error: no match for call to `(boost::function<const int&()(unsigned int)>) (const boost::lambda::lambda_ functor<boost::lambda::placeholder<1> >&)' -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux)
iD8DBQFJQA6L5vihyNWuA4URAkpdAKC5k4hqcrNPdsqTP5JUK5nehvALJQCgkHeo qeZcQpDkG9iq4pB6feb1Juk= =IY+7 -----END PGP SIGNATURE-----
participants (2)
-
Frank Mori Hess
-
Robert Jones