Question Regarding Boost 1.33.1 on MSVC.NET 2003

Hi all, I'm having a problem using Boost.Bind on the above platform. The simple test file I'm using looks like this: === snip === #include <iostream> #include <algorithm> #include <map> #include <boost/bind.hpp> struct Argument { int value_; }; struct Operator { Operator &compute(Argument const &arg) { std::cout << arg.value_ << std::endl; return *this; } // Warning is gone if I declare the above function as: //Operator const &compute(Argument const &arg) const {...} }; int main() { typedef std::map<int, Operator> OperatorMap; OperatorMap ops; ops.insert(std::make_pair(0, Operator())); Argument arg0 = { 1 }; std::for_each( ops.begin(), ops.end(), boost::bind(&Operator::compute, boost::bind(&OperatorMap::value_type::second, _1), boost::cref(arg0))); } === snip === The idea is that I want to put a parameter through a collection of Operators objects stored in an std::map. However, I always get the following warning from the compiler: === snip === test.cpp ..\..\..\boost-1.x\include\boost-1_33_1\boost\bind.hpp(276) : warning C4239: nonstandard extension used : 'argument' : conversion from 'boost::_bi::result_traits<R,F>::type' to 'Operator &' with [ R=Operator, F=boost::_mfi::dm<Operator,stlp_std::pair<const int,Operator>> ] A reference that is not to 'const' cannot be bound to a non-lvalue ..\..\..\boost-1.x\include\boost-1_33_1\boost\bind\bind_template.hpp(32) : see reference to function template instantiation 'R boost::_bi::list2<A1,A2>::operator ()<boost::_bi::bind_t<R,F,L>::result_type,F,boost::_bi::list1<stlp_std::pair<_T1,_T2> &>>(boost::_bi::type<T>,F &,A &,long)' being compiled with [ R=boost::_bi::bind_t<Operator &,boost::_mfi::mf1<Operator &,Operator,const Argument &>,boost::_bi::list2<boost::_bi::list_av_2<boost::_bi::bind_t<Operator,boost::_mfi::dm<Operator,stlp_std::pair<const int,Operator>>,boost::_bi::list1<boost::_bi::list_av_1<boost::arg<1>>::B1>>,Argument>::B1,boost::_bi::list_av_2<boost::_bi::bind_t<Operator,boost::_mfi::dm<Operator,stlp_std::pair<const int,Operator>>,boost::_bi::list1<boost::_bi::list_av_1<boost::arg<1>>::B1>>,Argument>::B2>>::result_type, A1=boost::_bi::list_av_2<boost::_bi::bind_t<Operator,boost::_mfi::dm<Operator,stlp_std::pair<const int,Operator>>,boost::_bi::list1<boost::_bi::list_av_1<boost::arg<1>>::B1>>,Argument>::B1, A2=boost::_bi::list_av_2<boost::_bi::bind_t<Operator,boost::_mfi::dm<Operator,stlp_std::pair<const int,Operator>>,boost::_bi::list1<boost::_bi::list_av_1<boost::arg<1>>::B1>>,Argument>::B2, F=boost::_mfi::mf1<Operator &,Operator,const Argument &>, L=boost::_bi::list2<boost::_bi::list_av_2<boost::_bi::bind_t<Operator,boost::_mfi::dm<Operator,stlp_std::pair<const int,Operator>>,boost::_bi::list1<boost::_bi::list_av_1<boost::arg<1>>::B1>>,Argument>::B1,boost::_bi::list_av_2<boost::_bi::bind_t<Operator,boost::_mfi::dm<Operator,stlp_std::pair<const int,Operator>>,boost::_bi::list1<boost::_bi::list_av_1<boost::arg<1>>::B1>>,Argument>::B2>, _T1=const int, _T2=Operator, T=boost::_bi::bind_t<Operator &,boost::_mfi::mf1<Operator &,Operator,const Argument &>,boost::_bi::list2<boost::_bi::list_av_2<boost::_bi::bind_t<Operator,boost::_mfi::dm<Operator,stlp_std:: pair<const int,Operator>>,boost::_bi::list1<boost::_bi::list_av_1<boost::arg<1>>::B1>>,Argument>::B1,boost::_bi::list_av_2<boost::_bi::bind_t<Operator,boost::_mfi::dm<Operator,stlp_std::pair<const int,Operator>>,boost::_bi::list1<boost::_bi::list_av_1<boost::arg<1>>::B1>>,Argument>::B2>>::result_type, A=boost::_bi::list1<stlp_std::map<int,Operator>::value_type &> ] ..\..\..\STLport-5.0\stlport\stl\_algo.h(61) : see reference to function template instantiation 'boost::_bi::bind_t<R,F,L>::result_type boost::_bi::bind_t<R,F,L>::operator ()<_Tp>(A1 &)' being compiled with [ R=Operator &, F=boost::_mfi::mf1<Operator &,Operator,const Argument &>, L=boost::_bi::list2<boost::_bi::list_av_2<boost::_bi::bind_t<Operator,boost::_mfi::dm<Operator,stlp_std::pair<const int,Operator>>,boost::_bi::list1<boost::_bi::list_av_1<boost::arg<1>>::B1>>,Argument>::B1,boost::_bi::list_av_2<boost::_bi::bind_t<Operator,boost::_mfi::dm<Operator,stlp_std::pair<const int,Operator>>,boost::_bi::list1<boost::_bi::list_av_1<boost::arg<1>>::B1>>,Argument>::B2>, _Tp=stlp_std::map<int,Operator>::value_type, A1=stlp_std::map<int,Operator>::value_type ] \workspace\devel\RD3.0-vc71\Libraries\MkToolkit-3.0\src\core\test.cpp(35) : see reference to function template instantiation '_Function stlp_std::for_each<stlp_std::map<_Key,_Tp>::iterator,boost::_bi::bind_t<R,F,L>>(_InputIter,_InputIter,_Function)' being compiled with [ _Function=boost::_bi::bind_t<Operator &,boost::_mfi::mf1<Operator &,Operator,const Argument &>,boost::_bi::list2<boost::_bi::list_av_2<boost::_bi::bind_t<Operator,boost::_mfi::dm<Operator,stlp_std::pair<const int,Operator>>,boost::_bi::list1<boost::_bi::list_av_1<boost::arg<1>>::B1>>,Argument>::B1,boost::_bi::list_av_2<boost::_bi::bind_t<Operator,boost::_mfi::dm<Operator,stlp_std::pair<const int,Operator>>,boost::_bi::list1<boost::_bi::list_av_1<boost::arg<1>>::B1>>,Argument>::B2>>, _Key=int, _Tp=Operator, R=Operator &, F=boost::_mfi::mf1<Operator &,Operator,const Argument &>, L=boost::_bi::list2<boost::_bi::list_av_2<boost::_bi::bind_t<Operator,boost::_mfi::dm<Operator,stlp_std::pair<const int,Operator>>,boost::_bi::list1<boost::_bi::list_av_1<boost::arg<1>>::B1>>,Argument>::B1,boost::_bi::list_av_2<boost::_bi::bind_t<Operator,boost::_mfi::dm<Operator,stlp_std::pair<const int,Operator>>,boost::_bi::list1<boost::_bi::list_av_1<boost::arg<1>>::B1>>,Argument>::B2>, _InputIter=stlp_std::map<int,Operator>::iterator ] === snip === It seems that it is complaining about the const-ness of Operator::compute() member function. May I know if there is anything I can do to fix this problem? Or, is there any problem with my understanding of Boost.Bind through the way I used it? Cheers, Freddie -- Wu Yinghui, Freddie Research & Development Software Engineer Volume Interactions Pte Ltd 1 Kim Seng Promenade, #12-01 Great World City East Tower Singapore 237994 Tel: +65 62226962 (Ext 216) Fax: +65 62226215 Email: yhwu@volumeinteractions.com URL: http://www.volumeinteractions.com Important: This message is intended for the recipient(s) addressed above. It contains privileged and confidential information. If you are not the intended recipient, please notify the sender immediately by replying to this message and then delete it from your system. You must not read, copy, use, or disseminate this communication in any form. Thank you.

Wu Yinghui, Freddie wrote:
struct Operator { Operator &compute(Argument const &arg) { std::cout << arg.value_ << std::endl; return *this; } // Warning is gone if I declare the above function as: //Operator const &compute(Argument const &arg) const {...} };
int main() { typedef std::map<int, Operator> OperatorMap;
OperatorMap ops; ops.insert(std::make_pair(0, Operator()));
Argument arg0 = { 1 };
std::for_each( ops.begin(), ops.end(), boost::bind(&Operator::compute, boost::bind(&OperatorMap::value_type::second, _1), boost::cref(arg0))); }
The problem is that boost::bind(&OperatorMap::value_type::second, _1) returns an Operator by value (in 1.33.1) or by const reference (in the current CVS). Since boost::bind needs to decide on a result type at bind time, and since it doesn't know whether the argument coming in from the _1 is const, it needs to conservatively assume const (Lambda doesn't have this limitation because it deduces the return type at call time). Use boost::bind<Operator&>(&OperatorMap::value_type::second, _1) to tell boost::bind to return a non-const reference.
participants (2)
-
Peter Dimov
-
Wu Yinghui, Freddie