title: This use of std::make_pair works fine in GCC 3 and 4. It fails in Visual Studio C++ 2010. Why?
body: <p>This compiles fine in GCC 3 and 4.  MSVC++ can't figure out the type of noFunction and throws some hideous errors.   Note if you cast noFunction to BFunction, it works just fine in VS2010.</p>
  
  <p><strong>My question: is this a defect in VS2010, or GCC bending the rules?</strong></p>
  
  <pre><code>#include &lt;map&gt;
  
  using namespace std;
  
  typedef bool (*AFunction)(int arg1, int arg2);
  typedef bool (*BFunction)(long arg1, bool arg2);
  
  bool noFunction(long, bool) { return true; }
  
  void test(AFunction a)
  {
  
      make_pair(a, noFunction); //fails in VS2010
  
  }
  </code></pre>
  
  <p><strong>N.B. casting noFunction to BFunction fixes the problem in VS2010.</strong></p>
  
  <pre><code>make_pair(a, (BFunction)noFunction);  //works everywhere
  </code></pre>
  
  <p>.</p>
  
  <p>.</p>
  
  <p>.</p>
  
  <p>Here is the error for reference:</p>
  
  <pre><code>    1&gt;  makepairtest.cpp
  1&gt;c:\program files (x86)\microsoft visual studio 10.0\vc\include\type_traits(197): error C2752: 'std::tr1::_Remove_reference&lt;_Ty&gt;' : more than one partial specialization matches the template argument list
  1&gt;          with
  1&gt;          [
  1&gt;              _Ty=bool (__cdecl &amp;)(long,bool)
  1&gt;          ]
  1&gt;          c:\program files (x86)\microsoft visual studio 10.0\vc\include\xtr1common(356): could be 'std::tr1::_Remove_reference&lt;_Ty&amp;&amp;&gt;'
  1&gt;          c:\program files (x86)\microsoft visual studio 10.0\vc\include\xtr1common(350): or       'std::tr1::_Remove_reference&lt;_Ty&amp;&gt;'
  1&gt;          c:\program files (x86)\microsoft visual studio 10.0\vc\include\type_traits(962) : see reference to class template instantiation 'std::tr1::remove_reference&lt;_Ty&gt;' being compiled
  1&gt;          with
  1&gt;          [
  1&gt;              _Ty=bool (__cdecl &amp;)(long,bool)
  1&gt;          ]
  1&gt;          c:\program files (x86)\microsoft visual studio 10.0\vc\include\utility(26) : see reference to class template instantiation 'std::tr1::decay&lt;_Ty&gt;' being compiled
  1&gt;          with
  1&gt;          [
  1&gt;              _Ty=bool (__cdecl &amp;)(long,bool)
  1&gt;          ]
  1&gt;          c:\xxx\makepairtest.cpp(14) : see reference to class template instantiation 'std::tr1::_Unrefwrap&lt;_Type&gt;' being compiled
  1&gt;          with
  1&gt;          [
  1&gt;              _Type=bool (__cdecl &amp;)(long,bool)
  1&gt;          ]
  1&gt;c:\program files (x86)\microsoft visual studio 10.0\vc\include\type_traits(965): error C2528: 'abstract declarator' : pointer to reference is illegal
  1&gt;c:\program files (x86)\microsoft visual studio 10.0\vc\include\type_traits(349): error C2528: 'type' : pointer to reference is illegal
  1&gt;          c:\program files (x86)\microsoft visual studio 10.0\vc\include\type_traits(967) : see reference to class template instantiation 'std::tr1::add_pointer&lt;_Ty&gt;' being compiled
  1&gt;          with
  1&gt;          [
  1&gt;              _Ty=bool (__cdecl &amp;)(long,bool)
  1&gt;          ]
  1&gt;c:\program files (x86)\microsoft visual studio 10.0\vc\include\utility(148): error C2535: 'std::_Pair_base&lt;_Ty1,_Ty2&gt;::_Pair_base(const _Ty1 &amp;,const _Ty2)' : member function already defined or declared
  1&gt;          with
  1&gt;          [
  1&gt;              _Ty1=bool (__cdecl *)(int,int),
  1&gt;              _Ty2=bool (__cdecl &amp;)(long,bool)
  1&gt;          ]
  1&gt;          c:\program files (x86)\microsoft visual studio 10.0\vc\include\utility(134) : see declaration of 'std::_Pair_base&lt;_Ty1,_Ty2&gt;::_Pair_base'
  1&gt;          with
  1&gt;          [
  1&gt;              _Ty1=bool (__cdecl *)(int,int),
  1&gt;              _Ty2=bool (__cdecl &amp;)(long,bool)
  1&gt;          ]
  1&gt;          c:\program files (x86)\microsoft visual studio 10.0\vc\include\utility(174) : see reference to class template instantiation 'std::_Pair_base&lt;_Ty1,_Ty2&gt;' being compiled
  1&gt;          with
  1&gt;          [
  1&gt;              _Ty1=bool (__cdecl *)(int,int),
  1&gt;              _Ty2=bool (__cdecl &amp;)(long,bool)
  1&gt;          ]
  1&gt;          c:\xxx\makepairtest.cpp(14) : see reference to class template instantiation 'std::pair&lt;_Ty1,_Ty2&gt;' being compiled
  1&gt;          with
  1&gt;          [
  1&gt;              _Ty1=bool (__cdecl *)(int,int),
  1&gt;              _Ty2=bool (__cdecl &amp;)(long,bool)
  1&gt;          ]
  </code></pre>