代码用g ++编译但在VC ++ 10中失败

时间:2012-09-11 17:08:26

标签: c++ visual-c++ g++

我正在将一些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 Files\Microsoft Visual Studio
10.0\VC\INCLUDE\xxresult(28) : error C2903: 'result' : symbol is neither a class template nor a function template
        C:\Program Files\Microsoft Visual Studio 10.0\VC\INCLUDE\xxresult(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 Files\Microsoft Visual Studio 10.0\VC\INCLUDE\xxresult(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 Files\Microsoft Visual Studio 10.0\VC\INCLUDE\xrefwrap(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 Files\Microsoft Visual Studio 10.0\VC\INCLUDE\xxbind1(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 Files\Microsoft Visual Studio 10.0\VC\INCLUDE\xxbind0(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 Files\Microsoft Visual Studio 10.0\VC\INCLUDE\functional(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 Files\Microsoft Visual Studio 10.0\VC\INCLUDE\xxresult(28) : error C2039: 'result' : is not a m ember of 'fopow<BaseT,ExpT>'
        with
        [
            BaseT=int,
            ExpT=int
        ] C:\Program Files\Microsoft Visual Studio 10.0\VC\INCLUDE\xxresult(28) : error C2143: syntax error : missin g ';' before '<' C:\Program Files\Microsoft Visual Studio
10.0\VC\INCLUDE\xxresult(28) : error C4430: missing type specifie r - int assumed. Note: C++ does not support default-int C:\Program Files\Microsoft Visual Studio 10.0\VC\INCLUDE\xxresult(28) : error C2039: 'type' : is not a mem ber of '`global namespace'' C:\Program Files\Microsoft Visual Studio 10.0\VC\INCLUDE\xxresult(28) : error C2238: unexpected token(s) p receding ';' C:\Program Files\Microsoft Visual Studio 10.0\VC\INCLUDE\xxresult(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 Files\Microsoft Visual Studio 10.0\VC\INCLUDE\xxresult(40) : error C2146: syntax error : missin g ';' before identifier '_Type' C:\Program Files\Microsoft Visual Studio
10.0\VC\INCLUDE\xxresult(40) : error C4430: missing type specifie r - int assumed. Note: C++ does not support default-int C:\Program Files\Microsoft Visual Studio 10.0\VC\INCLUDE\xxresult(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 Files\Microsoft Visual Studio 10.0\VC\INCLUDE\xxresult(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 Files\Microsoft Visual Studio 10.0\VC\INCLUDE\xxresult(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 ++的单一警告)。任何人都知道如何在不诉诸预处理魔法的情况下修复我的代码?

2 个答案:

答案 0 :(得分:2)

typedef BaseT result_type;添加到fopow的定义中。 decltype之前几天所需的模板hackery正在迷失,试图找出fopow::operator()的返回类型。 (而且,是的,你是对的:它在bind()电话中迷失了;特别是第一个电话。)

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

答案 1 :(得分:2)

std::bind不是你在VS2010中的想法:它实际上是std::tr1::bind,而是使用std::tr1::result_of,它比编译器辅助std::result_of强大得多。由C ++ 11标准强制执行。

特别是,不要尝试在VS10中使用std::bind和lambda表达式。

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