Opened 13 years ago

Closed 12 years ago

#4073 closed Bugs (fixed)

<boost/function/function_template.hpp> compile errors with Visual Studio 2010 - mem_fn ADL issue

Reported by: cpboost@… Owned by: Daniel James
Milestone: Boost 1.47.0 Component: function
Version: Boost 1.46.0 Severity: Problem
Keywords: argument dependent lookup, function, visual studio 2010. mem_fn Cc:

Description

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.

Attachments (1)

function_template_for_c++0x.patch (863 bytes ) - added by Conrad Poelman <cpboost@…> 12 years ago.
Patch file with the fix

Download all attachments as: .zip

Change History (10)

by Conrad Poelman <cpboost@…>, 12 years ago

Patch file with the fix

comment:1 by Jeremiah Willcock, 12 years ago

Resolution: fixed
Status: newclosed

(In [62623]) Applied patch from #4073; fixes #4073

comment:2 by alexander.limubei.kasper@…, 12 years ago

It seems this fix didn't make it into the official distributions. 1.43 and 1.44 do not contain this.

comment:3 by anonymous, 12 years ago

Milestone: Boost 1.43.0
Resolution: fixed
Status: closedreopened
Version: Boost 1.42.0Boost 1.44.0

I'm also seeing this problem with 1.44. The supplied patch seems to fix it, but needs to be applied in the released library.

comment:4 by anonymous, 12 years ago

Version: Boost 1.44.0Boost 1.45.0

This is also present in 1.45. The supplied patch fixes it in 1.45 as well.

comment:5 by anonymous, 12 years ago

Version: Boost 1.45.0Boost 1.46.0

Reported in 1.42

Present in: 1.42, 1.43, 1.44, 1.45

Still present in 1.46

The supplied fix for 1.42 still works, please apply it to the released version.

comment:6 by Daniel James, 12 years ago

Owner: changed from Douglas Gregor to Daniel James
Status: reopenednew

Seems to be fixed on trunk but not in the release branch. I'll look into merging outstanding function changes once the release cycle starts.

comment:7 by Daniel James, 12 years ago

Status: newassigned

comment:8 by Daniel James, 12 years ago

Milestone: Boost 1.47.0

comment:9 by Daniel James, 12 years ago

Resolution: fixed
Status: assignedclosed

(In [70361]) Function: Merge from trunk.

  • Remove extra definition of operator(), since it's inline anyway. Fixes #4765.
  • Make sure that the cv flags are copied when we copy a reference to a function object. Fixes #4325
  • Fully qualified function calls to avoid ambiguity with new additions to standard. Thanks to Conrad Poelman. Fixes #4073
  • Remove iterator workaround for newer versions of Visual Age C++. Thanks to 'ccambly'. Fixes #3912
  • Fix unused variable warning for Visual C++. Fixes #3618
  • Testing flag for Visual C++.
  • Removed all but one old-style cast, prevents GCC warnings, but breaks GCC 2.95.3. Fixes #3410
  • Fixed tab and newline issues from inspection report.
Note: See TracTickets for help on using tickets.