[phoenix] binding member_functions

Hi there, I think there are some problems with binding functions if the class has a const and a non-const version of the same member. Please consider the following code: #include <boost/spirit/include/phoenix_algorithm.hpp> #include <boost/spirit/include/phoenix_bind.hpp> #include <boost/spirit/include/phoenix_container.hpp> #include <boost/spirit/include/phoenix_core.hpp> #include <boost/spirit/include/phoenix_function.hpp> #include <boost/spirit/include/phoenix_fusion.hpp> #include <boost/spirit/include/phoenix_object.hpp> #include <boost/spirit/include/phoenix_operator.hpp> #include <boost/spirit/include/phoenix_scope.hpp> #include <boost/spirit/include/phoenix_statement.hpp> #include <boost/spirit/include/phoenix_stl.hpp> #include <algorithm> #include <iostream> #include <fstream> #include <vector> using namespace std; using namespace boost::phoenix; using namespace boost::phoenix::arg_names; struct point { point() {} point( double prob, double x ) : _prob( prob ), _x( x ) {} double& prob() { return _prob; } double& x() { return _x; } const double& prob() const { return _prob; } const double& x() const { return _x; } void set_prob( const double& prob ) { _prob = prob; } void set_x ( const double& x ) { _x = x; } private: double _prob; double _x; }; int _tmain(int argc, _TCHAR* argv[]) { typedef vector< point > distribution_t; distribution_t d( 1 ); const distribution_t& dr = d; // works typedef const double& ( point::* pp_t )() const; double sum_prob = std::accumulate( dr.begin() , dr.end() , 0.0 , arg1 + bind( static_cast<pp_t>(&point::prob), arg2 ) ); // doesn't work sum_prob = std::accumulate( dr.begin() , dr.end() , 0.0 , arg1 + bind( &point::prob, arg2 ) ); return 0; } Only when I explicitly state which member phoenix is swallowing it. I don't think that should be required. Steven. When do you think you will apply the patches? Thanks, Christian

Christian Henning wrote:
Hi there, I think there are some problems with binding functions if the class has a const and a non-const version of the same member. Please consider the following code:
[snips] No, it's not a bug. When you get the address of a member function, there is relly no way in C++ to know which overload you want to get. You have to state it explicitly with a cast. The same thing happens with Boost.Bind, for example, try: point const p; double x = boost::bind( &point::prob, _1 )(p); and you'll get the exact same error. The Boost Bind docs has a good explanation on this. See "Binding an overloaded function" here: http://www.boost.org/doc/libs/1_37_0/libs/bind/bind.html#Troubleshooting Regards, -- Joel de Guzman http://www.boostpro.com http://spirit.sf.net

Thanks Joel, for you explanation. Do you think that maybe for c++0x that problem is resolved? Also, do the C++ lambda function suffer from the same problem? Christian On Mon, Nov 10, 2008 at 8:37 PM, Joel de Guzman <joel@boost-consulting.com> wrote:
Christian Henning wrote:
Hi there, I think there are some problems with binding functions if the class has a const and a non-const version of the same member. Please consider the following code:
[snips]
No, it's not a bug. When you get the address of a member function, there is relly no way in C++ to know which overload you want to get. You have to state it explicitly with a cast.
The same thing happens with Boost.Bind, for example, try:
point const p; double x = boost::bind( &point::prob, _1 )(p);
and you'll get the exact same error. The Boost Bind docs has a good explanation on this. See "Binding an overloaded function" here:
http://www.boost.org/doc/libs/1_37_0/libs/bind/bind.html#Troubleshooting
Regards, -- Joel de Guzman http://www.boostpro.com http://spirit.sf.net
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users

Christian Henning wrote:
Thanks Joel, for you explanation. Do you think that maybe for c++0x that problem is resolved?
No I don't think so. Also, do the C++ lambda function suffer from
the same problem?
With C++ lambda, you don't have to do the bind dance. Regards, -- Joel de Guzman http://www.boostpro.com http://spirit.sf.net
participants (2)
-
Christian Henning
-
Joel de Guzman