Categories: MSDN / DotNet / Java / Scripts / Linux / PHP Ask - La ask - La Answer

min max

Hello,

I have :-

#define NOMINMAX

string::size_type maxlen = 10;
maxlen = max(maxlen, 14);

I've read that VC++ does not support min max and has _cpp_max instead. However, I'm not sure how to use it. Also, does it take the same parameters as the max above (not int) ?

Thanks,

Imanuel.
[354 byte] By [ami] at [2007-11-11 10:06:30]
# 1 Re: min max
What version of VC++ do you have? VC++ 2005 surely has max and min function templates, so there shouldn't be any problem.
dcwexter at 2007-11-11 20:59:24 >
# 2 Re: min max
Vc++ 6.0
ami at 2007-11-11 21:00:24 >
# 3 Re: min max
max_element() And min_element() .
Amahdy at 2007-11-11 21:01:28 >
# 4 Re: min max
min_element and max_element search for max and min elements in range defined by two two iterators and optionaly predicate function. VC++ 6.0, however defines max and min as macros. As a quick fix, you could add your own definitions of min and max as function templates.

Here is possible implementation:

template<class CMPTYPE> inline
const CMPTYPE& max(const CMPTYPE& _Left, const CMPTYPE& _Right)
{ // return larger of _Left and _Right
return (_Left < _Right ? _Right : _Left);
}
// TEMPLATE FUNCTION max WITH PRED
template<class CMPTYPE, class PREDFUN> inline
const CMPTYPE& max(const CMPTYPE& _Left, const CMPTYPE& _Right, PREDFUN _Pred)
{ // return larger of _Left and _Right using _Pred
return (_Pred(_Left,_Right) ? _Right : _Left);
}
// TEMPLATE FUNCTION min
template<class CMPTYPE> inline
const CMPTYPE& min(const CMPTYPE& _Left, const CMPTYPE& _Right)
{ // return smaller of _Left and _Right
return (_Right < _Left ? _Right : _Left);
}
// TEMPLATE FUNCTION min WITH PRED
template<class CMPTYPE, class PREDFUN> inline
const CMPTYPE& min(const CMPTYPE& _Left, const CMPTYPE& _Right, PREDFUN _Pred)
{ // return smaller of _Left and _Right using _Pred
return (_Pred(_Right, Left) ? _Right : _Left);
}

Add this snippet in <algorithm> header, but make sure that you add it between _STD_BEGIN and _STD_END defines. When calling this code, always use 'std::max' or 'std::min' instead of plain 'max' and 'min' to avoid any possible ambiguity.

#include <algorithm>
#include <iostream>
#include <string>
using namespace std;

int main()
{
string::size_type maxlen = 10;
maxlen = std::max<int>(maxlen, 14);
cout << maxlen << endl;

return 0;
}

In your example there could be one little problem, but if you are acustomed to templates, the solution will appear obvious. The thing is you use two different types: 'maxlen' and '14' are typed as 'unsigned int' and 'int' respectively (at least with my version of vc++6.0). So what happens when you try to compile your original code?

string::size_type maxlen = 10;
maxlen = max(maxlen, 14);

Template instatation mechanism will find that your max template has one template parameter, which is CMPTYPE. But you are providing two different types (int and unsigned int). When dealing with templates, compiler omits standard conversions, as it usually does when compiling "normal" functions. So you need to provide explicitly type that all arguments will be converted to. You do it like this:

max<int>( maxlen, 14 );

Now you should only add std:: qualification to your calls, and that's about it. For example:

cout << std::max<int>( maxlen, 14 ) << endl;

If you are calling 'std::min' and 'std::max' with arguments that are exactly the same type, then you simply omit argument type, like this:

cout << std::max( -3, 14 ) << endl;

Hope this helps.
dcwexter at 2007-11-11 21:02:33 >
# 5 Re: min max
Excellent answer, dcwexter!
Danny at 2007-11-11 21:03:27 >
# 6 Re: min max
thanks :o
dcwexter at 2007-11-11 21:04:26 >
# 7 Re: min max
Excellent. All works great.

One final question: where did you get the min and max templates from ? How do people need to know when to update include directives such as <algorithm> ? Could I just put it in a normal h file and include that instead ?
ami at 2007-11-11 21:05:36 >
# 8 Re: min max
There are no "normal h files" in standard C++. All standard libraries are defined in files with names such as <iostream>, <algorithm> etc.
Knowing which header to #include is part of C++ knowledge. There aren't so many of them anyway, and the names are quite meaningful. For example, all STL algorithms are defined in <algorithm>, all file stream operations and classes in <fstream> and so on.
However, rarely do you need to *implement* the algorithms on your own. If you used a more up-to-date version of VC++ you'd simply need to #include <algorithm> and then call std::max(x,y);.
Danny at 2007-11-11 21:06:28 >
# 9 Re: min max
Implementation of min and max is trivial and is often used as an example when presenting templates so you should find one easily. One I gave you is modified version of templates found in STL implementation that comes with VS2005. In general, you shouldn't be doing any modifications to the STL, but in cases like this, when implementation is missing, or even worse wrong you can get your hands dirty by doing it yourself properly. Of course, I asume that you know C++ enogh well to do such work corectly.

min and max templates are part of C++ standard and as such they should have their place in <algorithm> header (or should be visible through it). If you have significant number of custom made algorithms, you should consider creating your own library. You could also check boost (http://www.boost.org) library for already proven concepts/implementations.
dcwexter at 2007-11-11 21:07:37 >
# 10 Re: min max
One more thing. If you have interest in templates (and enough time :)) you could check on this title:

C++ Templates - The Complete Guide (http://www.josuttis.com/tmplbook/)

The book provides essential material on templates, and some basic concepts and tehniques that are most useful when it comes to generic programming and design. Also, authors asume that you know little or nothing about templates (BUT ARE CONFIDENT IN ALL OTHER PARTS OF C++) which makes it a pretty good starter.
dcwexter at 2007-11-11 21:08:32 >