Visual studio 2010 std::make_对的这种使用在GCC 3和GCC 4中工作得很好。它在Visual Studio C+中失败+;2010为什么?

Visual studio 2010 std::make_对的这种使用在GCC 3和GCC 4中工作得很好。它在Visual Studio C+中失败+;2010为什么?,visual-studio-2010,stl,compiler-errors,Visual Studio 2010,Stl,Compiler Errors,这在GCC 3和GCC 4中编译得很好。MSVC++无法确定noFunction的类型,并抛出了一些可怕的错误。注意,如果您将noFunction强制转换为BFunction,它在VS2010中就可以正常工作 我的问题:这是VS2010中的缺陷,还是GCC违反了规则? #include <map> using namespace std; typedef bool (*AFunction)(int arg1, int arg2); typedef bool (*BFunction

这在GCC 3和GCC 4中编译得很好。MSVC++无法确定noFunction的类型,并抛出了一些可怕的错误。注意,如果您将noFunction强制转换为BFunction,它在VS2010中就可以正常工作

我的问题:这是VS2010中的缺陷,还是GCC违反了规则?

#include <map>

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

}

以下是供参考的错误:

    1>  makepairtest.cpp
1>c:\program files (x86)\microsoft visual studio 10.0\vc\include\type_traits(197): error C2752: 'std::tr1::_Remove_reference<_Ty>' : more than one partial specialization matches the template argument list
1>          with
1>          [
1>              _Ty=bool (__cdecl &)(long,bool)
1>          ]
1>          c:\program files (x86)\microsoft visual studio 10.0\vc\include\xtr1common(356): could be 'std::tr1::_Remove_reference<_Ty&&>'
1>          c:\program files (x86)\microsoft visual studio 10.0\vc\include\xtr1common(350): or       'std::tr1::_Remove_reference<_Ty&>'
1>          c:\program files (x86)\microsoft visual studio 10.0\vc\include\type_traits(962) : see reference to class template instantiation 'std::tr1::remove_reference<_Ty>' being compiled
1>          with
1>          [
1>              _Ty=bool (__cdecl &)(long,bool)
1>          ]
1>          c:\program files (x86)\microsoft visual studio 10.0\vc\include\utility(26) : see reference to class template instantiation 'std::tr1::decay<_Ty>' being compiled
1>          with
1>          [
1>              _Ty=bool (__cdecl &)(long,bool)
1>          ]
1>          c:\xxx\makepairtest.cpp(14) : see reference to class template instantiation 'std::tr1::_Unrefwrap<_Type>' being compiled
1>          with
1>          [
1>              _Type=bool (__cdecl &)(long,bool)
1>          ]
1>c:\program files (x86)\microsoft visual studio 10.0\vc\include\type_traits(965): error C2528: 'abstract declarator' : pointer to reference is illegal
1>c:\program files (x86)\microsoft visual studio 10.0\vc\include\type_traits(349): error C2528: 'type' : pointer to reference is illegal
1>          c:\program files (x86)\microsoft visual studio 10.0\vc\include\type_traits(967) : see reference to class template instantiation 'std::tr1::add_pointer<_Ty>' being compiled
1>          with
1>          [
1>              _Ty=bool (__cdecl &)(long,bool)
1>          ]
1>c:\program files (x86)\microsoft visual studio 10.0\vc\include\utility(148): error C2535: 'std::_Pair_base<_Ty1,_Ty2>::_Pair_base(const _Ty1 &,const _Ty2)' : member function already defined or declared
1>          with
1>          [
1>              _Ty1=bool (__cdecl *)(int,int),
1>              _Ty2=bool (__cdecl &)(long,bool)
1>          ]
1>          c:\program files (x86)\microsoft visual studio 10.0\vc\include\utility(134) : see declaration of 'std::_Pair_base<_Ty1,_Ty2>::_Pair_base'
1>          with
1>          [
1>              _Ty1=bool (__cdecl *)(int,int),
1>              _Ty2=bool (__cdecl &)(long,bool)
1>          ]
1>          c:\program files (x86)\microsoft visual studio 10.0\vc\include\utility(174) : see reference to class template instantiation 'std::_Pair_base<_Ty1,_Ty2>' being compiled
1>          with
1>          [
1>              _Ty1=bool (__cdecl *)(int,int),
1>              _Ty2=bool (__cdecl &)(long,bool)
1>          ]
1>          c:\xxx\makepairtest.cpp(14) : see reference to class template instantiation 'std::pair<_Ty1,_Ty2>' being compiled
1>          with
1>          [
1>              _Ty1=bool (__cdecl *)(int,int),
1>              _Ty2=bool (__cdecl &)(long,bool)
1>          ]
1>makepairtest.cpp
1> c:\program files(x86)\microsoft visual studio 10.0\vc\include\type\u traits(197):错误C2752:“std::tr1::\u Remove\u reference”:多个部分专门化与模板参数列表匹配
1> 与
1>          [
1> _Ty=bool(u cdecl&)(长,bool)
1>          ]
1> c:\program files(x86)\microsoft visual studio 10.0\vc\include\xtr1common(356):可以是“std::tr1::\u Remove\u reference”
1> c:\ProgramFiles(x86)\microsoft visual studio 10.0\vc\include\xtr1common(350):或“std::tr1::_Remove\u reference”
1> c:\ProgramFiles(x86)\microsoft visual studio 10.0\vc\include\type\u traits(962):请参阅对正在编译的类模板实例化“std::tr1::remove\u reference”的引用
1> 与
1>          [
1> _Ty=bool(u cdecl&)(长,bool)
1>          ]
1> c:\ProgramFiles(x86)\microsoft visual studio 10.0\vc\include\utility(26):请参阅正在编译的类模板实例化“std::tr1::decay”的参考
1> 与
1>          [
1> _Ty=bool(u cdecl&)(长,bool)
1>          ]
1> c:\xxx\makepairtest.cpp(14):请参阅对正在编译的类模板实例化“std::tr1::\u Unrefwrap”的引用
1> 与
1>          [
1> 类型=bool(长,bool)
1>          ]
1> c:\ProgramFiles(x86)\microsoft visual studio 10.0\vc\include\type\u traits(965):错误C2528:“抽象声明器”:指向引用的指针非法
1> c:\program files(x86)\microsoft visual studio 10.0\vc\include\type\u traits(349):错误C2528:“type”:指向引用的指针非法
1> c:\ProgramFiles(x86)\microsoft visual studio 10.0\vc\include\type\u traits(967):请参阅正在编译的类模板实例化“std::tr1::add\u pointer”的参考
1> 与
1>          [
1> _Ty=bool(u cdecl&)(长,bool)
1>          ]
1> c:\program files(x86)\microsoft visual studio 10.0\vc\include\utility(148):错误C2535:“std::\u Pair\u base::\u Pair\u base(const\u Ty1&,const\u Ty2)”:成员函数已定义或声明
1> 与
1>          [
1> _Ty1=bool(u cdecl*)(int,int),
1> _Ty2=bool(u cdecl&)(长,bool)
1>          ]
1> c:\ProgramFiles(x86)\microsoft visual studio 10.0\vc\include\utility(134):请参阅“std::\u Pair\u base::\u Pair\u base”的声明
1> 与
1>          [
1> _Ty1=bool(u cdecl*)(int,int),
1> _Ty2=bool(u cdecl&)(长,bool)
1>          ]
1> c:\ProgramFiles(x86)\microsoft visual studio 10.0\vc\include\utility(174):请参阅正在编译的类模板实例化“std::\u Pair\u base”的参考
1> 与
1>          [
1> _Ty1=bool(u cdecl*)(int,int),
1> _Ty2=bool(u cdecl&)(长,bool)
1>          ]
1> c:\xxx\makepairtest.cpp(14):请参阅对正在编译的类模板实例化“std::pair”的引用
1> 与
1>          [
1> _Ty1=bool(u cdecl*)(int,int),
1> _Ty2=bool(u cdecl&)(长,bool)
1>          ]

使用
noFunction
的地址与VC10和gcc 4.5.2一起使用,即:

make_pair(a, &noFunction);
根据您发布的错误消息,我猜这与VC如何处理绑定到右值有关。

我的问题:这是VS2010中的一个缺陷,还是GCC违反了规则

当有疑问时,请责怪Visual C++和/或比尔盖茨。请注意,在代码中使用noFunction的值与BFunction定义的类型之间存在差异。noFunction将是函数的引用,而BFunction定义了函数的指针。这有点难以解释,但考虑一下下面的计划可能会有所帮助

#include <iostream>
#include <typeinfo>


bool noFunction(long, bool) { return true; }

typedef bool (function_ref)(long, bool);
typedef bool (*function_ptr)(long, bool);

int
main()
{
    std::cout << typeid(noFunction).name() << '\n';
    std::cout << typeid(&noFunction).name() << '\n';
    std::cout << typeid(function_ref).name() << '\n';
    std::cout << typeid(function_ptr).name() << '\n';

    return 0;
}
#包括
#包括
bool noFunction(long,bool){return true;}
typedef bool(函数_ref)(长,bool);
类型定义布尔(*函数_ptr)(长,布尔);
int
main()
{

std::cout将地址转换为预期的类型有什么好处?使用您现在使用的C样式转换,您可能会认为
typedef
可能会更改,并且类型可能会失去同步,而您的编译器不会帮助您捕获它。如果您使用
static\u cast
,我可以看到的唯一好处是n考虑的是更少的键入;)(使用地址vs
static\u caat
ing)使用“address of”运算符比使用强制转换的优点是,强制转换将允许您意外地传递指向错误函数类型的指针。
#include <iostream>
#include <typeinfo>


bool noFunction(long, bool) { return true; }

typedef bool (function_ref)(long, bool);
typedef bool (*function_ptr)(long, bool);

int
main()
{
    std::cout << typeid(noFunction).name() << '\n';
    std::cout << typeid(&noFunction).name() << '\n';
    std::cout << typeid(function_ref).name() << '\n';
    std::cout << typeid(function_ptr).name() << '\n';

    return 0;
}