代码使用g++编译,但使用VC++10失败

Code Compiles with g++ but Fails with VC++ 10

本文关键字:VC++10 失败 编译 g++ 代码      更新时间:2023-10-16

我正在将一些Linux程序移植到Windows。我想确保我的代码使用MinGW和Visual C++10编译,而不需要太多的#define#ifdef魔法。除了这道题,我已经解决了大部分的问题。我有一个类似于下面的代码,它可以用g++4.6.3编译,但不能用Visual C++10:

#include <iostream>
#include <vector>
#include <array>
#include <algorithm>
#include <functional>
#include <cmath>
#include <iterator>
typedef unsigned char UINT8;
const UINT8 MAX_COLL = 10;
template< typename BaseT, typename ExpT >
struct fopow {
    BaseT operator() ( BaseT base, ExpT exp ) const {
        return std::pow( base, exp );
    }
};
int main() {
    using namespace std;
    using namespace std::placeholders;
    array<int, MAX_COLL> intCollection_init = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    vector<int> intCollection( intCollection_init.begin(), intCollection_init.end() );
    transform( intCollection.begin(), intCollection.end(),
               ostream_iterator<int>( cout, " " ),
               bind( fopow<int, int>(), 3, _1 )
            );
    cout << endl;
    transform( intCollection.begin(), intCollection.end(),
               ostream_iterator<int>( cout, " " ),
               bind( fopow<int, int>(), _1, 3 )
            );
    cout << endl;
}

编译器的输出对我来说甚至根本无法理解:

Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.40219.01 for 80x86
Copyright (C) Microsoft Corporation.  All rights reserved.
Test2.cpp C:Program FilesMicrosoft Visual Studio
10.0VCINCLUDExxresult(28) : error C2903: 'result' : symbol is neither a class template nor a function template
        C:Program FilesMicrosoft Visual Studio 10.0VCINCLUDExxresult(40) : see reference to class tem plate instantiation 'std::tr1::_Result_type2<__formal,_Fty,_Arg0,_Arg1>' being compiled
        with
        [
            __formal=false,
            _Fty=fopow<int,int>,
            _Arg0=std::tr1::_Nil &,
            _Arg1=std::tr1::_Nil &
        ]
        C:Program FilesMicrosoft Visual Studio 10.0VCINCLUDExxresult(597) : see reference to class te mplate instantiation 'std::tr1::_Result_of2<_Fty,_Farg0,_Farg1>' being compiled
        with
        [
            _Fty=fopow<int,int>,
            _Farg0=std::tr1::_Nil &,
            _Farg1=std::tr1::_Nil &
        ]
        C:Program FilesMicrosoft Visual Studio 10.0VCINCLUDExrefwrap(28) : see reference to class tem plate instantiation 'std::tr1::_Result_of<_Ty>' being compiled
        with
        [
            _Ty=fopow<int,int> (std::tr1::_Nil &,std::tr1::_Nil &)
        ]
        C:Program FilesMicrosoft Visual Studio 10.0VCINCLUDExxbind1(273) : see reference to class tem plate instantiation 'std::tr1::result_of<_Fty>' being compiled
        with
        [
            _Fty=fopow<int,int> (std::tr1::_Nil &,std::tr1::_Nil &)
        ]
        C:Program FilesMicrosoft Visual Studio 10.0VCINCLUDExxbind0(10) : see reference to class temp late instantiation 'std::tr1::_Bind2<_Callable,_Arg0,_Arg1>::_Return<_Barg0,_Barg1,_Barg2,_Barg3,_Barg4,_B arg5,_Barg6,_Barg7,_Barg8,_Barg9>' being compiled
        with
        [
            _Callable=std::tr1::_Callable_obj<fopow<int,int>,false>,
            _Arg0=int,
            _Arg1=std::tr1::_Ph<1>,
            _Barg0=std::tr1::_Nil &,
            _Barg1=std::tr1::_Nil &,
            _Barg2=std::tr1::_Nil &,
            _Barg3=std::tr1::_Nil &,
            _Barg4=std::tr1::_Nil &,
            _Barg5=std::tr1::_Nil &,
            _Barg6=std::tr1::_Nil &,
            _Barg7=std::tr1::_Nil &,
            _Barg8=std::tr1::_Nil &,
            _Barg9=std::tr1::_Nil &
        ]
        C:Program FilesMicrosoft Visual Studio 10.0VCINCLUDEfunctional(408) : see reference to class template instantiation 'std::tr1::_Bind_base<_Ret,_BindN>' being compiled
        with
        [
            _Ret=std::tr1::_Notforced,
            _BindN=std::tr1::_Bind2<std::tr1::_Callable_obj<fopow<int,int>,false>,int,std::tr1::_Ph<1>>
        ]
        Test2.cpp(26) : see reference to class template instantiation 'std::tr1::_Bind_fty<_Fty,_Ret,_Bind N>' being compiled
        with
        [
            _Fty=fopow<int,int>,
            _Ret=std::tr1::_Notforced,
            _BindN=std::tr1::_Bind2<std::tr1::_Callable_obj<fopow<int,int>,false>,int,std::tr1::_Ph<1>>
        ] C:Program FilesMicrosoft Visual Studio 10.0VCINCLUDExxresult(28) : error C2039: 'result' : is not a m ember of 'fopow<BaseT,ExpT>'
        with
        [
            BaseT=int,
            ExpT=int
        ] C:Program FilesMicrosoft Visual Studio 10.0VCINCLUDExxresult(28) : error C2143: syntax error : missin g ';' before '<' C:Program FilesMicrosoft Visual Studio
10.0VCINCLUDExxresult(28) : error C4430: missing type specifie r - int assumed. Note: C++ does not support default-int C:Program FilesMicrosoft Visual Studio 10.0VCINCLUDExxresult(28) : error C2039: 'type' : is not a mem ber of '`global namespace'' C:Program FilesMicrosoft Visual Studio 10.0VCINCLUDExxresult(28) : error C2238: unexpected token(s) p receding ';' C:Program FilesMicrosoft Visual Studio 10.0VCINCLUDExxresult(40) : error C2039: '_Type' : is not a me mber of 'std::tr1::_Result_type2<__formal,_Fty,_Arg0,_Arg1>'
        with
        [
            __formal=false,
            _Fty=fopow<int,int>,
            _Arg0=std::tr1::_Nil &,
            _Arg1=std::tr1::_Nil &
        ] C:Program FilesMicrosoft Visual Studio 10.0VCINCLUDExxresult(40) : error C2146: syntax error : missin g ';' before identifier '_Type' C:Program FilesMicrosoft Visual Studio
10.0VCINCLUDExxresult(40) : error C4430: missing type specifie r - int assumed. Note: C++ does not support default-int C:Program FilesMicrosoft Visual Studio 10.0VCINCLUDExxresult(40) : error C2602: 'std::tr1::_Result_of 2<_Fty,_Farg0,_Farg1>::_Type' is not a member of a base class of 'std::tr1::_Result_of2<_Fty,_Farg0,_Farg1
>'
        with
        [
            _Fty=fopow<int,int>,
            _Farg0=std::tr1::_Nil &,
            _Farg1=std::tr1::_Nil &
        ]
        C:Program FilesMicrosoft Visual Studio 10.0VCINCLUDExxresult(40) : see declaration of 'std::t r1::_Result_of2<_Fty,_Farg0,_Farg1>::_Type'
        with
        [
            _Fty=fopow<int,int>,
            _Farg0=std::tr1::_Nil &,
            _Farg1=std::tr1::_Nil &
        ] C:Program FilesMicrosoft Visual Studio 10.0VCINCLUDExxresult(40) : error C2868: 'std::tr1::_Result_of 2<_Fty,_Farg0,_Farg1>::_Type' : illegal syntax for using-declaration; expected qualified-name
        with
        [
            _Fty=fopow<int,int>,
            _Farg0=std::tr1::_Nil &,
            _Farg1=std::tr1::_Nil &
        ]

我认为问题的根源是bind()或transform(),但我不知道代码到底出了什么问题(因为它编译得很好,没有一个g++警告)。有人知道如何在不使用前置器魔法的情况下修复我的代码吗?

std::bind并不是您在VS2010中想象的那样:它实际上是std::tr1::bind,并且使用了std::tr1::result_of,其功能远不如C++11标准所要求的编译器辅助的std::result_of强大。

特别是,不要尝试将std::bind与VS10中的lambda表达式一起使用。

您可以在此处通过让fopow继承std::binary_function<BaseT, ExpT, BaseT>来解决此问题。

typedef BaseT result_type;添加到fopow的定义中。在decltype之前的几天里所需要的模板技巧在试图弄清楚fopow::operator()的返回类型时正在丢失。(是的,你是对的:它在bind()调用中丢失了;特别是在第一个调用中。)

或者,如果您愿意,您可以使用@ecatmur建议的修复程序:从std::binary_function<BaseT, ExpT, BaseT>派生。这也将向模板中添加result_type,以及first_argument_typesecond_argument_typebind不需要参数类型。