Re: std::max(unsigned, size_t), amd64 and C++0x
Gabriel Dos Reis ha scritto:
Alberto Ganesh Barbati <AlbertoBarbati@libero.it> writes:
[...]
| With such a definition, common_type<> could be safely used as the return
| value of
functions like min and max:
|
| template <class T, class U>
| common_type<T, U>::type auto_min(T, U);
|
| auto x = auto_min(-1, 1u);
| assert(x == -1);
|
| of course x won't be neither an int nor an unsigned int, but of some
| signed integer type capable of representing the whole range of both.
I never needed (note, I'm not sating I cannot construct artifical
cases) such version of `max()', where it would really make my codes more
maintainable or readable.
It would be a mistake to include common_type<> in C++0x solely based
on speculations similar to the quoted above.
I think I found a better case, which, I believe, could actually be
considered a defect in the current wording. Consider this:
using Dur1 = std::time_duration<int>;
using Dur2 = std::time_duration<unsigned>;
Dur1 d1(-1);
Dur2 d2(0);
assert(d1 > d2); // ??? should be the opposite!
This is because common_type<int, unsigned>::type is unsigned, so
common_type<Dur1, Dur2>::type is Dur2. operator< converts both arguments
to the common type (i.e. Dur2) but when you convert d1 to Dur2 the
integer -1 is converted to 2^n-1 for some n, which is greater than 0.
If, on the other hand, common_type<int, unsigned>::type could be any
integer type able to represent the entire ranges of int and unsigned, we
would have no problem.
Similarly if you write:
auto d = d1 + d2; //decltype(d) is Dur2
d loses its sign and represents a positive duration. If this code occurs
in a template where the types of d1 and d2 are template arguments, the
user may not (and should not) be concerned with the exact type of d as
long as the operation returns the correct result. In this case having
decltype(d) use a integer representation larger than both d1 and d2 is
not inappropriate, IMHO.
This is similar to the well known:
int i = -1;
unsigned u = 0;
assert(i > u); // !!!
auto x = i + u; // x > 0!
but while in this case the compiler can reasonably detect the potential
error and issue a warning message, in the duration<> case the mistake
will probably go unnoticed because there is an explicit cast.
Ganesh
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]