views:

683

answers:

5
template <class T>
struct scalar_log_minimum {
public:
 typedef T value_type;
 typedef T result_type;
 static
  result_type initial_value(){
   return std::log(std::numeric_limits<result_type>::max());
 }
 static
  void update(result_type& t, const value_type& x){
   if ( (x>0) && (std::log(x)<t) ) t = std::log(x);
 }
};

i got the following error while trying to compile the above:

functional_ext.hpp:55:59: macro "max" requires 2 arguments, but only 1 given

max is not a macro, right? Then what is this error? BTW, I am using visual studio 2005

Also what is 55:59 --- 55 is the line number 59?

+4  A: 

You're including a header file somewhere that #defines max as a macro. The best solution would be to figure out where it's being defined, and inhibit it from being defined if possible. Alternatively, you could just #undef it:

#include <evil_header_which_defines_max.h>
#undef max
Adam Rosenfield
I had similar problems with MSVC, I think it's in their library headers.
jpalecek
windef.h (usually included via windows.h) contains such an offending define and frequently causes headaches for STL users.
timday
+1  A: 

It's a macro called max that gets into the way as Adam explained. Another solution (more a "hotfix") may be to put parentheses around the function, to prevent it from being seen as a macro invocation:

return std::log((std::numeric_limits<result_type>::max)());
Johannes Schaub - litb
A: 

Thanks to the above two, I have corrected it.

But I am facing more subtler error.

I have an overloaded function min()

So, now I get the same error. Can you suggest some fix to this?

rboorgapally
you can just wrap the min in parentheses too. but it's more a "hotfix". for really solving it, you should try to undef min and max or prevent windows from defining it (i heard there is a WIN32_LEAN_AND_MEAN macro which makes it not define so much macros)
Johannes Schaub - litb
+1  A: 

I find the many #defines that you encounter once you included windows.h very disturbing (not only max and min, but I also had problems with other generic words like Rectangle if I'm not mistaken). Therefore, I have developed the habit to include windows.h only when absolutely necessary, and never in header files. This reduces the pain to a small number of C++ files that are platform-specific.

Unfortunately some boost libraries (I believe thread and asio) do include windows.h in their headers, and I still run into this kind of silly problems from time to time.

My solution for the remainder of the situations where this causes problems is to #undef the problematic symbols after the inclusion of the header files.

A: 

As others have noted, including windows.h is probably your problem. Microsoft provides a means to "turn off" parts of windows.h with preprocessor symbols. You can define these symbols as part of your build or directly in code.

Using preprocessor symbols to conditionally skip sections of windows.h may or may not be considered elegant but in the general case it is an easier, more general and more scalable solution than #undef.

Here's how to skip defining min or max as macros:

#define NOMINMAX
#include <windows.h>

Note that many include files will, at some point, include windows.h. In such cases setting up your defines at a more global level may be more convenient.

If you search through windows.h, you can find a bunch of other preprocessor symbols (e.g., NOOPENFILE, NOKANJI, NOKERNEL and many others) that can often be useful.

jwfearn