Tex
Tex

Reputation: 45

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

I'm in the process of porting some of my Linux programs to Windows. I would like to make sure my codes compile with both MinGW and Visual C++ 10 without too much #define and #ifdef magic. I've managed to work out most of the problems, except this one. I have a code similar to the following, which compiles fine with g++ 4.6.3 but not with 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;
}

The compiler output is not even remotely intelligible to me:

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 &
        ]

I think the root of the problem is bind() or transform() but I don't know what exactly is wrong with the code (as it compiles fine without a single warning with g++). Anyone knows how to fix my code without resorting to prepocessor magics?

Upvotes: 2

Views: 1458

Answers (2)

Alexandre C.
Alexandre C.

Reputation: 56986

std::bind is not what you think it is in VS2010: it is in fact std::tr1::bind, and uses std::tr1::result_of, which is much less powerful than the compiler-assisted std::result_of mandated by the C++11 standard.

In particular, don't try to use std::bind with lambda-expressions in VS10.

You can resolve this here by having fopow inherit std::binary_function<BaseT, ExpT, BaseT>.

Upvotes: 2

Pete Becker
Pete Becker

Reputation: 76458

Add typedef BaseT result_type; to the definition of fopow. The template hackery that was needed in the days before decltype is getting lost trying to figure out what the return type of fopow::operator() is. (And, yes, you're right: it's getting lost in the bind() call; specifically, the first one.)

Or, if you like, you can use the fix suggested by @ecatmur: derive from std::binary_function<BaseT, ExpT, BaseT>. That will also add result_type to the template, as well as first_argument_type and second_argument_type. bind doesn't need the argument types.

Upvotes: 2

Related Questions