macro “max” requires 2 arguments, but only 1 given

2020-04-05 19:14发布

问题:

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?

回答1:

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.



回答2:

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


回答3:

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.



回答4:

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)());