On Mon, Nov 30, 2009 at 2:37 PM, mmoll
<Markus.Moll@xxxxxxxxxxxxxxxx> wrote:
> The last error is really strange. I tried to play a little bit with
> it and
> it seems that std::pow(std::complex<double>(2), int) is returning a
> std::complex<float>. At least I get the error message "conversion
> from
> 'std::complex<double>' to non-scalar type 'const
> std::complex<float>'
> requested" when I try the following code
>
> const Scalar tmp = std::pow(Scalar(2), m_squarings);
> MatrixType A = *m_M / tmp;
This actually indicates the opposite, that std::pow returns a
complex<double> for arguments of type complex<float>.
The conversion constructors that might lose precision (e.g.
complex<double> to complex<float>) have always been explicit, so my
guess is that the rules for overload resolution have changed.
If m_squarings is a double, the call is pow(complex<float>, double).
Probably the compiler previously preferred the conversion double->float
(wow, although it loses precision), but now prefers complex<float> ->
complex<double> (which makes more sense actually). But maybe the type of
m_squarings changed for some reason or previous versions of GCC treated
complex<double> -> complex<float> less strictly than required?
Yeah, true - it's the conversion from double to float. Thanks for the hint since it lead me to the solution. ;)
So this is what seems to happen. When __GXX_EXPERIMENTAL_CXX0X__ is enabled, "complex<_Tp> pow(const complex<_Tp>& __z, int __n)" does not exist any more - from C++0x on, the standard seems to require you to use this "complex<_Tp> pow(const complex<_Tp>& __x, const _Tp& __y)" signature. As a matter of fact I did not find the implementation that caused the generation of a double complex return type. At least not in the complex header. Anyways, changing the implementation to
MatrixType A = *m_M / std::pow(Scalar(2), m_Scalar(squarings));
solves the issue and makes everything future proof.
- Hauke