Hello, looking at this question: http://stackoverflow.com/q/21737186/1918193I was surprised to see that libstdc++'s std::complex basically just works with user-defined types, even weird expression template ones, although that's not a supported use afaik.
The only functions that fail seem to be exp and pow, both because they call polar with two arguments that have different (expression) types.
I am not proposing to make this a supported use, but the cost of this small patch seems very low, and if it makes a couple users happy...
Regtested with no problem on x86_64-linux-gnu, ok for stage 1? 2014-02-23 Marc Glisse <marc.gli...@inria.fr> * include/std/complex (__complex_exp, pow): Specify the template parameter in calls to std::polar, for expression templates. -- Marc Glisse
Index: libstdc++-v3/include/std/complex =================================================================== --- libstdc++-v3/include/std/complex (revision 208045) +++ libstdc++-v3/include/std/complex (working copy) @@ -728,21 +728,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #else template<typename _Tp> inline complex<_Tp> cosh(const complex<_Tp>& __z) { return __complex_cosh(__z); } #endif // 26.2.8/3 exp(__z): Returns the complex base e exponential of x template<typename _Tp> inline complex<_Tp> __complex_exp(const complex<_Tp>& __z) - { return std::polar(exp(__z.real()), __z.imag()); } + { return std::polar<_Tp>(exp(__z.real()), __z.imag()); } #if _GLIBCXX_USE_C99_COMPLEX inline __complex__ float __complex_exp(__complex__ float __z) { return __builtin_cexpf(__z); } inline __complex__ double __complex_exp(__complex__ double __z) { return __builtin_cexp(__z); } inline __complex__ long double __complex_exp(const __complex__ long double& __z) @@ -988,21 +988,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION pow(const complex<_Tp>& __x, const _Tp& __y) { #ifndef _GLIBCXX_USE_C99_COMPLEX if (__x == _Tp()) return _Tp(); #endif if (__x.imag() == _Tp() && __x.real() > _Tp()) return pow(__x.real(), __y); complex<_Tp> __t = std::log(__x); - return std::polar(exp(__y * __t.real()), __y * __t.imag()); + return std::polar<_Tp>(exp(__y * __t.real()), __y * __t.imag()); } template<typename _Tp> inline complex<_Tp> __complex_pow(const complex<_Tp>& __x, const complex<_Tp>& __y) { return __x == _Tp() ? _Tp() : std::exp(__y * std::log(__x)); } #if _GLIBCXX_USE_C99_COMPLEX inline __complex__ float __complex_pow(__complex__ float __x, __complex__ float __y) @@ -1025,22 +1025,22 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Tp> inline complex<_Tp> pow(const complex<_Tp>& __x, const complex<_Tp>& __y) { return __complex_pow(__x, __y); } #endif template<typename _Tp> inline complex<_Tp> pow(const _Tp& __x, const complex<_Tp>& __y) { - return __x > _Tp() ? std::polar(pow(__x, __y.real()), - __y.imag() * log(__x)) + return __x > _Tp() ? std::polar<_Tp>(pow(__x, __y.real()), + __y.imag() * log(__x)) : std::pow(complex<_Tp>(__x), __y); } /// 26.2.3 complex specializations /// complex<float> specialization template<> struct complex<float> { typedef float value_type; typedef __complex__ float _ComplexT;