[phoenix] adding const to member_variable bind

Hi there, the following code doesn't compile since I'm iterating over a constant vector of points. struct point { double _prob; double _x; }; void test( const std::vector< point >& d ) { double sum_prob = std::accumulate( d.begin() , d.end() , 0.0 , arg1 + bind( &point::_prob, arg2 ) ); } int _tmain(int argc, _TCHAR* argv[]) { std::vector< point > d; test( d ); return 0; } My question is how can I convert or cast the "&point::_prob" into a const reference? I tried several ways but they all don't work. The only thing that worked was to add const getter function in my point structure. Like this: struct point { point( double prob, double x ) : _prob( prob ), _x( x ) {} const double& prob() const { return _prob; } double _prob; double _x; }; Thanks, Christian

Thanks Steven, that worked. With your last statement I assume you mean
it should have worked even without the explicit cast. I had the same
feeling.
Christian
On Tue, Nov 4, 2008 at 4:06 PM, Steven Watanabe
AMDG
Christian Henning wrote:
My question is how can I convert or cast the "&point::_prob" into a const reference?
static_cast
(&point::_prob) should work, but really, this is a bug in phoenix. Patch against the trunk attached. In Christ, Steven Watanabe
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users

Steven Watanabe wrote:
AMDG
Christian Henning wrote:
My question is how can I convert or cast the "&point::_prob" into a const reference?
static_cast
(&point::_prob) should work, but really, this is a bug in phoenix. Patch against the trunk attached.
Thanks, Steven. Please feel free to apply the patch. Regards, -- Joel de Guzman http://www.boostpro.com http://spirit.sf.net

AMDG Steven Watanabe wrote:
Joel de Guzman wrote:
Thanks, Steven. Please feel free to apply the patch.
I've started adding this to bind_member_variable_tests.cpp and I'm running into more problems than I expected. I'll get back to you.
I'm stuck here: struct x { int m; }; // instantiates member_variable::result<x>, // but calls member_variable::operator()(const x&). bind(&x::m, x())(); // instantiates member_variable::result<x> because // top level references are stripped. bind(&x::m, ref(x)); There is no way for result to distinguish between these cases, even though they are different. In Christ, Steven Watanabe

Steven Watanabe wrote:
AMDG
Steven Watanabe wrote:
Joel de Guzman wrote:
Thanks, Steven. Please feel free to apply the patch.
I've started adding this to bind_member_variable_tests.cpp and I'm running into more problems than I expected. I'll get back to you.
I'm stuck here:
struct x { int m; };
// instantiates member_variable::result<x>, // but calls member_variable::operator()(const x&). bind(&x::m, x())();
// instantiates member_variable::result<x> because // top level references are stripped. bind(&x::m, ref(x));
There is no way for result to distinguish between these cases, even though they are different.
Out of curiosity, how does Boost.Bind and Lambda.Bind behave in this regard? Regards, -- Joel de Guzman http://www.boostpro.com http://spirit.sf.net

AMDG Joel de Guzman wrote:
There is no way for result to distinguish between these cases, even though they are different.
Out of curiosity, how does Boost.Bind and Lambda.Bind behave in this regard?
It looks like:
a) bind always constifies the return type of a pointer to a data member.
b) lambda does not strip references in its return type deduction.
#include

Steven Watanabe wrote:
AMDG
Joel de Guzman wrote:
There is no way for result to distinguish between these cases, even though they are different.
Out of curiosity, how does Boost.Bind and Lambda.Bind behave in this regard?
It looks like: a) bind always constifies the return type of a pointer to a data member. b) lambda does not strip references in its return type deduction.
[...]
void boost_phoenix() { namespace phoenix = boost::phoenix; x x_ = {0}; phoenix::bind(&x::m, phoenix::val(x_))(); // does not compile phoenix::bind(&x::m, phoenix::ref(x_))() = 1; phoenix::bind(&x::m, phoenix::cref(x_))(); // does not compile }
The third is ok with your patch. Anyway, ok, this is a bug due to, as you noticed, stripping of the top level reference. Seems it's a limitation of the old result-type scheme. I think it can only be fixed when we move to the result_of protocol which respects the references. Anyway, I added your test (which fails the val(x) test and your patch (which allows the cref(x) test). I'll keep the failing val(x) test to remind me to fix this bug. Regards, -- Joel de Guzman http://www.boostpro.com http://spirit.sf.net

Steven Watanabe wrote:
AMDG
Joel de Guzman wrote:
Anyway, I added your test (which fails the val(x) test and your patch (which allows the cref(x) test). I'll keep the failing val(x) test to remind me to fix this bug.
Here's a more thorough test case.
Cool. Feel free to add these tests. Regards, -- Joel de Guzman http://www.boostpro.com http://spirit.sf.net
participants (3)
-
Christian Henning
-
Joel de Guzman
-
Steven Watanabe