|  | min max |  | |
| | | Guest |  |
| Posted: Tue Sep 02, 2008 1:41 am Post subject: min max |  |
| |  | |
An article from Andrei Alexandrescu got me thinking about the min/max problem a couple of months ago. It's really ridiculous that such a simple concept like max() won't work with 2 different integral types, in a modern programming language, without additional casting. This is especially annoying because compiler errors related to min/max are often platform specific, as pointed out in the original post.
Unfortunately, there doesn't seem to be any ideal solution. The best I could come up with is a system which assigns "weights" representing relative width to each integral type, and then computes the return type based on which type is wider. This can be done as follows:
template <class T> struct type_weight { static const int value = 16; };
template <> struct type_weight<bool> { static const int value = 1; }; template <> struct type_weight<char> { static const int value = 2; }; template <> struct type_weight<signed char> { static const int value = 3; }; template <> struct type_weight<unsigned char> { static const int value = 4; }; template <> struct type_weight<short> { static const int value = 5; }; template <> struct type_weight<unsigned short> { static const int value = 6; }; template <> struct type_weight<wchar_t> { static const int value = 7; }; template <> struct type_weight<int> { static const int value = 8; }; template <> struct type_weight<unsigned int> { static const int value = 9; }; template <> struct type_weight<long> { static const int value = 10; }; template <> struct type_weight<unsigned long> { static const int value = 11; }; template <> struct type_weight<unsigned long long> { static const int value = 12; }; template <> struct type_weight<float> { static const int value = 13; }; template <> struct type_weight<double> { static const int value = 14; }; template <> struct type_weight<long double> { static const int value = 15; };
template <class T1, class T2> inline typename boost::mpl::eval_if<(type_weight<T1>::value > type_weight<T2>::value), T1, T2>::type max(const T1& t1, const T2& t2) { typedef typename boost::mpl::eval_if<(type_weight<T1>::value > type_weight<T2>::value), T1, T2>::type return_type;
if (t1 > t2) return return_type(t1); return return_type(t2); }
Of course, this is far from ideal. For one thing it won't work properly if T1 and T2 are both non-POD objects. Secondly, it returns a value instead of a reference, which is also a big negative with non- PODs. Finally, it has the same limitation as std::max in that it doesn't work with lvalue assignment. So overall, it's not so great an improvement, but at least it helps with a lot of common cases where two different integral types are compared, such as the case in the original post.
The root of the problem is that since the compiler can't possibly know which argument will be greater at runtime, T1 needs to be implicitly convertible to T2 and vice versa, so that either argument can be returned as a return_type. But this prohibits returning a reference, since a new instance of t1 or t2 needs to be generated for the implicit conversion to return_type.
-- [ See LINK for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |
| |
| | | Andrei Alexandrescu |  |
| Posted: Wed Sep 03, 2008 8:35 am Post subject: Re: min max |  |
Alberto Ganesh Barbati wrote:
| Quote: | chsalvia@gmail.com ha scritto: An article from Andrei Alexandrescu got me thinking about the min/max problem a couple of months ago. It's really ridiculous that such a simple concept like max() won't work with 2 different integral types, in a modern programming language, without additional casting. This is especially annoying because compiler errors related to min/max are often platform specific, as pointed out in the original post.
Please see the ongoing thread titled "std::max(unsigned, size_t), amd64 and C++0x".
|
To avoid further backs and forths: I myself recommended Charles to look at that thread and also to post his code because I think he has an original and interesting word to say in the matter.
Andrei
-- [ See LINK for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |
| |
|
|