Re: std::norm defect?
On 4 Mrz., 08:49, highegg <high...@gmail.com> wrote:
Just an update: I've sent the GCC developers the following patch to
the "complex" header:
Index: libstdc++-v3/include/std/complex
=========================
==========================
==================
--- libstdc++-v3/include/std/complex (revision 144596)
+++ libstdc++-v3/include/std/complex (working copy)
@@ -649,8 +649,13 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
template<typename _Tp>
static inline _Tp _S_do_it(const complex<_Tp>& __z)
{
- _Tp __res = std::abs(__z);
- return __res * __res;
+ const _Tp __x = abs(__z.real());
+ const _Tp __y = abs(__z.imag());
+ const _Tp __s = std::max(__x, __y);
+ const _Tp __r = std::min(__x, __y);
+ if (__s == _Tp())
+ return __s;
+ return __s * (__s + __r * (__r / __s));
}
};
This is me just nit-picking: You used qualified names for max and min.
In generic user code this is discouraged because it prevents ADL. But
ADL is all you have left if you want min/max calls to resolve to your
own function templates:
namespace mymath
{
template<typename Integer> class rational;
template<typename Integer>
rational<Integer> min(rational<Integer> const& a,
rational<Integer> const& b);
}
This is the only possibility because you can't partially specialize
std::min and std::max. Also, overloading them in the namespace "std"
is illegal as far as the C++ standard is concerned (it usually works,
though).
So, in generic user code (some other namespace than std) you would
write:
template<typename T>
T do_it(const complex<_Tp>& __z)
{
using std::min;
using std::max;
...
const T s = max(x,y); // ADL still works
}
If I remember correctly this is covered in "Effective C++" by Scott
Meyers.
Cheers!
SG