在VS2010中调用Winsock(winsock or winsock2)的bind函数时很有可能会出现一些莫名其妙的错误而导致编译失败,控制台输出的错误信息指向了库中的xxresult,和程序本身的设计似乎没有任何关联。
控制台片段:
1>c:/program files/microsoft visual studio 10.0/vc/include/xxresult(28): error C2825: '_Fty': must be a class or namespace when followed by '::'
1> c:/program files/microsoft visual studio 10.0/vc/include/xxresult(40) : see reference to class template instantiation 'std::tr1::_Result_type2<__formal,_Fty,_Arg0,_Arg1>' being compiled
1> with
1> [
1> __formal=false,
1> _Fty=__w64 unsigned int,
1> _Arg0=std::tr1::_Nil &,
1> _Arg1=std::tr1::_Nil &
1> ]
1> c:/program files/microsoft visual studio 10.0/vc/include/xxresult(597) : see reference to class template instantiation 'std::tr1::_Result_of2<_Fty,_Farg0,_Farg1>' being compiled
实际上这是由于在VS2010中Winsock的 bind()与TR1(C++ Technical Report 1)的bind() 冲突导致的。在VS2010中微软将TR1中的bind()声明在名称空间 std 中,而Winsock的bind() 则声明在全域(global namespace),当在代码中使用“using namespace std ”这样的语句引入整个名称空间后,由于此时存在两个bind(),且TR1的bind()是一个模板在编译器重载解析时具有较高的优先级,直接调用bind()将导致了TR1对Winsock调用的覆盖,接下来在编译阶段的类型错误就不足为怪了。
解决的方法很简单,只要让编译器能够正确区别两者就可以了。为了解决由于使用"using namespace std"带来的冲突,我们需要在全域调用时显式的声明,如 “::bind()” ,这样编译器就只会在全域中解析该函数的调用,而不会导致冲突。以后遇到类似的情况,都可以通过全域声明(::call())来解决。
本文由VS软件圈(vssoft.net)发布,不代表VS软件圈立场,转载联系作者并注明出处:https://vssoft.net/vsazwt/VS2010anzhuangwenti/2020/0724/2476.html