[Boost-bugs] [Boost C++ Libraries] #4073: <boost/function/function_template.hpp> compile errors with Visual Studio 2010 - mem_fn ADL issue

Subject: [Boost-bugs] [Boost C++ Libraries] #4073: <boost/function/function_template.hpp> compile errors with Visual Studio 2010 - mem_fn ADL issue
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2010-04-06 00:40:04


#4073: <boost/function/function_template.hpp> compile errors with Visual Studio
2010 - mem_fn ADL issue
-----------------------------------------------------------------------------+
 Reporter: cpboost@… | Owner: dgregor
     Type: Bugs | Status: new
Milestone: Boost 1.43.0 | Component: function
  Version: Boost 1.42.0 | Severity: Problem
 Keywords: argument dependent lookup, function, visual studio 2010. mem_fn |
-----------------------------------------------------------------------------+
 '''Problem:'''
 Using boost::function in Microsoft Visual Studio 2010 can cause an
 argument-dependent name lookup problem when given arguments that include
 std:: components. I ''believe'' this will happen with any compiler that
 has mem_fn in the std:: namespace, but have only verified it on VS 2010.

 '''Solution:'''
 Change two instances of mem_fn in function_template.hpp (lines 539 and 552
 of the current Subversion checkout) to prefix them with the boost::
 namespace qualifier. It appears that this is already done at the other two
 mem_fn calls at lines 207 & 225.

 '''How to Reproduce'''
 Build the following code with Visual Studio 2010:

 {{{
 #include <boost/function.hpp>
 #include <string>

 class PrimitiveBuilder
 {
 public:
   bool someFunction( std::string& token );
   void registerSomeFunction() {
     mPrimitiveFunctor = &PrimitiveBuilder::someFunction; // ambiguity
 error is here
 }
 private:
   typedef boost::function<bool (PrimitiveBuilder*, std::string& token)>
 PrimitiveFunctor;
   PrimitiveFunctor mPrimitiveFunctor;
 };
 }}}


 It will produce the following error message:

 {{{
 1>e:\stellar\controlled\trunk\3rdparty\boost\boost\function\function_template.hpp(539):
  error C2668: 'boost::mem_fn' : ambiguous call to overloaded function
 1>
 e:\stellar\controlled\trunk\3rdparty\boost\boost\bind\mem_fn_cc.hpp(25):
  could be 'boost::_mfi::mf1<R,T,A1>
 boost::mem_fn<bool,PrimitiveBuilder,std::string&>
  (R (__thiscall PrimitiveBuilder::* )(A1))'
 1> with
 1> [
 1> R=bool,
 1> T=PrimitiveBuilder,
 1> A1=std::string &
 1> ]
 1> c:\program files (x86)\microsoft visual studio
 10.0\vc\include\xxmem_fn(32):
  or 'std::tr1::_Mem_fn2<_Rx,_Pmf,_Arg0,_Arg1>
 std::tr1::mem_fn<bool,PrimitiveBuilder,std::string&>
  (_Rx (__thiscall PrimitiveBuilder::* )(_Arg1))' [found using argument-
 dependent lookup]
 1> with
 1> [
 1> _Rx=bool,
 1> _Pmf=bool (__thiscall PrimitiveBuilder::* )(std::string &),
 1> _Arg0=PrimitiveBuilder,
 1> _Arg1=std::string &
 1> ]
 1> while trying to match the argument list '(bool (__thiscall
 PrimitiveBuilder::* )(std::string &))'

 }}}

 '''More problem explanation'''
 Deep inside of boost there's a call to "this->assign_to_a(mem_fn(f),
 functor, a);". mem_fn used to be unambiguous, but now because one of our
 function's arguments is an std::string, the new std::mem_fn is introduced
 as a candidate. I verified that if I change std::string to int in the
 above example, the code compiles fine. I've also verified that the
 solution - adding "boost::" in front of the two unqualified mem_fn calls -
 resolved the problem.

-- 
Ticket URL: <https://svn.boost.org/trac/boost/ticket/4073>
Boost C++ Libraries <http://www.boost.org/>
Boost provides free peer-reviewed portable C++ source libraries.

This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:02 UTC