这在GCC 3和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
}
N.B。将noFunction转换为BFunction修复了VS2010中的问题。
make_pair(a, (BFunction)noFunction); //works everywhere
以下是参考错误:
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> ]
答案 0 :(得分:2)
将noFunction
的地址与VC10和gcc 4.5.2一起使用,即:
make_pair(a, &noFunction);
根据您发布的错误消息,我猜它与VC如何处理与rvalues的绑定有关。
答案 1 :(得分:1)
“我的问题:这是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;
}
似乎Visual C ++在函数引用上窒息。我不确定是否有合理的理由拒绝它,但我希望你能够构建一个具有可复制构造模型的类型。例如,您应该能够构建但不能分配std::pair<int, int const&>
。