By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
454,134 Members | 1,195 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 454,134 IT Pros & Developers. It's quick & easy.

GCC/MSVC++ difference

P: n/a
I have a bit of code that doesn't compile under MSVC++ but does under
GCC. Even under GCC, though, it seems odd that I don't need a std
namespace qualifier for the exp function.

Is this just one of those difference I have to #ifdef around, or is
there a bit of code that will compile under both?

Basically, I have a std::vector<double>. I want to replace each item
in the vector with the exp() of that item. The code does work, and
there's a simple work-around under Window's, but I'd prefer to
understand why it doesn't compile.

Below is the code and the VC++ error message. The workaround is to
replace exp with locExp in the call to transform.

Thanks for any suggestions!
Andrew
Version info:
Visual Studio 2005, Academic Edition, Version 8.0.50727.42
Visual C++ 2005 77633-233-0020534-41001

g++: powerpc-apple-darwin8-g++-4.0.1
Compiling...
transform.cpp
c:\documents and settings\asalamon\my documents\test
\transform.cpp(45) : error C2780: '_OutIt
std::transform(_InIt1,_InIt1,_InIt2,_OutIt,_Fn2)' : expects 5
arguments - 4 provided
c:\program files\microsoft visual studio 8\vc\include
\algorithm(797) : see declaration of 'std::transform'
c:\documents and settings\asalamon\my documents\test
\transform.cpp(45) : error C2914: 'std::transform' : cannot deduce
template argument as function argument is ambiguous
c:\documents and settings\asalamon\my documents\test
\transform.cpp(45) : error C2784: '_OutIt
std::transform(_InIt,_InIt,_OutIt,_Fn1)' : could not deduce template
argument for '_OutIt' from 'std::_Vector_iterator<_Ty,_Alloc>'
with
[
_Ty=double,
_Alloc=std::allocator<double>
]
c:\program files\microsoft visual studio 8\vc\include
\algorithm(682) : see declaration of 'std::transform'
Build log was saved at "file://c:\Documents and Settings\asalamon\My
Documents\Test\testTransform\testTransform\Debug\B uildLog.htm"
testTransform - 3 error(s), 0 warning(s)
// Begin code
#include <iomanip>
#include <vector>
#include <algorithm>
#include <iostream>
#include <cmath// for exp()

void testTransformExp();

int main()
{
testTransformExp();
}

void printVec( std::vector<double&vec )
{
for( unsigned int i = 0; i < vec.size(); ++i )
std::cout << vec[i] << ", ";
std::cout << std::endl;
}

inline double locExp( double val )
{
return exp(val);
}

void testTransformExp()
{
std::vector<doubleres( 8, 0.0 );

res[0] = 1.0;
res[1] = 2.0;
res[2] = 10.0;
res[3] = 30.0;
res[4] = 100.0;
res[5] = 400.0;
res[6] = 1000.0;
res[7] = 5000.0;

std::transform( res.begin(), res.end(), res.begin(), exp ); //
calculate the exponent of each element
printVec( res );
}

Mar 12 '07 #1
Share this Question
Share on Google+
6 Replies


P: n/a
bl*************@gmail.com wrote:
I have a bit of code that doesn't compile under MSVC++ but does under
GCC. Even under GCC, though, it seems odd that I don't need a std
namespace qualifier for the exp function.

std::transform( res.begin(), res.end(), res.begin(), exp );
printVec( res );
}
exp, having extern "C" linkage, probably doesn't match std::transform's
UnaryOperation template parameter.

--
Ian Collins.
Mar 12 '07 #2

P: n/a
<bl*************@gmail.comwrote in message
news:11*********************@j27g2000cwj.googlegro ups.com...
>I have a bit of code that doesn't compile under MSVC++ but does under
GCC. Even under GCC, though, it seems odd that I don't need a std
namespace qualifier for the exp function.

Is this just one of those difference I have to #ifdef around, or is
there a bit of code that will compile under both?

Basically, I have a std::vector<double>. I want to replace each item
in the vector with the exp() of that item. The code does work, and
there's a simple work-around under Window's, but I'd prefer to
understand why it doesn't compile.

Below is the code and the VC++ error message. The workaround is to
replace exp with locExp in the call to transform.
Right. The problem you face is that VC++ conforms better to the C++
Standard than does GCC. The former provides the required overloads
for exp; the latter is at the mercy of the underlying C library to
provide those overloads, and certainly glibc fails to do so. By
interposing the wrapper function, you disambiguate the call to
transform.

HTH,

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com
Mar 12 '07 #3

P: n/a
On Mar 12, 2:26 pm, "P.J. Plauger" <p...@dinkumware.comwrote:
>
Right. The problem you face is that VC++ conforms better to the C++
Standard than does GCC. The former provides the required overloads
for exp; the latter is at the mercy of the underlying C library to
provide those overloads, and certainly glibc fails to do so. By
interposing the wrapper function, you disambiguate the call to
transform.

HTH,

P.J. Plauger
Dinkumware, Ltd.http://www.dinkumware.com
I'm not sure if it helps my understanding much, but thanks! Looking
through the cmath header file, it certainly seems like there are
overloads for exp, but that's why I didn't understand why I don't need
a std:: qualifier for exp. Maybe the __enable_if... macro prevents any
re-definition of exp?

<snipped from parts of cmath>
#undef exp
....
namespace std
{
using ::exp;

inline float
exp(float __x)
{ return __builtin_expf(__x); }

inline long double
exp(long double __x)
{ return __builtin_expl(__x); }

template<typename _Tp>
inline typename __enable_if<double,
__is_integer<_Tp>::__value>::__type
exp(_Tp __x)
{ return __builtin_exp(__x); }
}

I did come up with what seems like a cleaner way to fix it, though:

typedef double (*expType) (double);
std::transform( res.begin(), res.end(), res.begin(),
static_cast<expType>(exp) );

It builds and runs properly under both compilers. I guess I'll just
leave it at that for now, since it does seem to work.

Thanks!
Andrew

Mar 12 '07 #4

P: n/a
In article <11**********************@c51g2000cwc.googlegroups .com>,
bl*************@gmail.com wrote:
On Mar 12, 2:26 pm, "P.J. Plauger" <p...@dinkumware.comwrote:

Right. The problem you face is that VC++ conforms better to the C++
Standard than does GCC. The former provides the required overloads
for exp; the latter is at the mercy of the underlying C library to
provide those overloads, and certainly glibc fails to do so. By
interposing the wrapper function, you disambiguate the call to
transform.

HTH,

P.J. Plauger
Dinkumware, Ltd.http://www.dinkumware.com

I'm not sure if it helps my understanding much, but thanks! Looking
through the cmath header file, it certainly seems like there are
overloads for exp, but that's why I didn't understand why I don't need
a std:: qualifier for exp. Maybe the __enable_if... macro prevents any
re-definition of exp?

<snipped from parts of cmath>
#undef exp
...
namespace std
{
using ::exp;

inline float
exp(float __x)
{ return __builtin_expf(__x); }

inline long double
exp(long double __x)
{ return __builtin_expl(__x); }

template<typename _Tp>
inline typename __enable_if<double,
__is_integer<_Tp>::__value>::__type
exp(_Tp __x)
{ return __builtin_exp(__x); }
}

I did come up with what seems like a cleaner way to fix it, though:

typedef double (*expType) (double);
std::transform( res.begin(), res.end(), res.begin(),
static_cast<expType>(exp) );

It builds and runs properly under both compilers. I guess I'll just
leave it at that for now, since it does seem to work.
What happens if you use std::exp instead of exp. Technically that is
all that should be exposed by <cmathtoday.

-Howard
Mar 12 '07 #5

P: n/a
On Mar 12, 3:55 pm, Howard Hinnant <howard.hinn...@gmail.comwrote:
In article <1173735917.931039.118...@c51g2000cwc.googlegroups .com>,

What happens if you use std::exp instead of exp. Technically that is
all that should be exposed by <cmathtoday.

-Howard
With this line:
std::transform( res.begin(), res.end(), res.begin(), std::exp );

For gcc:
transform.cpp: In function 'void testTransformExp()':
transform.cpp:46: error: no matching function for call to
'transform(__gnu_cxx::__normal_iterator<double*, std::vector<double,
std::allocator<double >, __gnu_cxx::__normal_iterator<double*,
std::vector<double, std::allocator<double >,
__gnu_cxx::__normal_iterator<double*, std::vector<double,
std::allocator<double >, <unknown type>)'

And a similar error from VC++ (sorry, can't copy/paste from Windows):
error C2780 ... expects 5 arguments - 4 provided
.... can't deduce template argument as function argument is ambiguous
....

Mar 12 '07 #6

P: n/a
bl*************@gmail.com wrote:
I have a bit of code that doesn't compile under MSVC++ but does under
GCC. Even under GCC, though, it seems odd that I don't need a std
namespace qualifier for the exp function.

Is this just one of those difference I have to #ifdef around, or is
there a bit of code that will compile under both?

Basically, I have a std::vector<double>. I want to replace each item
in the vector with the exp() of that item. The code does work, and
there's a simple work-around under Window's, but I'd prefer to
understand why it doesn't compile.

Below is the code and the VC++ error message. The workaround is to
replace exp with locExp in the call to transform.

Thanks for any suggestions!
Andrew
[snip]
// Begin code
#include <iomanip>
#include <vector>
#include <algorithm>
#include <iostream>
#include <cmath// for exp()

void testTransformExp();

int main()
{
testTransformExp();
}

void printVec( std::vector<double&vec )
{
for( unsigned int i = 0; i < vec.size(); ++i )
std::cout << vec[i] << ", ";
std::cout << std::endl;
}

inline double locExp( double val )
{
return exp(val);
}

void testTransformExp()
{
std::vector<doubleres( 8, 0.0 );

res[0] = 1.0;
res[1] = 2.0;
res[2] = 10.0;
res[3] = 30.0;
res[4] = 100.0;
res[5] = 400.0;
res[6] = 1000.0;
res[7] = 5000.0;

std::transform( res.begin(), res.end(), res.begin(), exp );
I think, the compiler needs some help to chose the right overload for
std::exp:

std::transform( res.begin(), res.end(), res.begin(),
static_cast< double(*)(double)( std::exp ) );

[snip]
printVec( res );
}

Best

Kai-Uwe Bux
Mar 13 '07 #7

This discussion thread is closed

Replies have been disabled for this discussion.