76

I have the following template declaration:

template <typename T>
   void IterTable(int&                       rIdx,
                  std::vector<double>&       rVarVector,
                  const std::vector<T>&      aTable,
                  const T                    aValue,
                  T              aLowerBound = -(std::numeric_limits<T>::max()), //illegal token on right side of '::' shows here
                  bool                       aLeftOpen = true) const;

Which throws the illegal token error as noted, on the line with "-(std::numeric_limits::max())". I got this code from some old linux source that I'm trying to compile on Windows. Any idea what the issue is?

Edit: It also fails using min(), and the compiler output is:

Error   92  error C2589: '::' : illegal token on right side of '::' c:\projects\r&d\prepaydll\include\cfcdefault.h  216 PrepayDLL

Error   93  error C2059: syntax error : '::'    c:\projects\r&d\prepaydll\include\cfcdefault.h  216 PrepayDLL

Line 216, is the line previously mentioned.

Adam Haile
  • 30,705
  • 58
  • 191
  • 286

3 Answers3

174

My guess is that max has been made a macro. This happens at some point inside windows.h.

Define NOMINMAX prior to including to stop windows.h from doing that.

EDIT:

I'm still confident this is your problem. (Not including <limits> would result in a different error). Place #undef max and #undef min just before the function and try again. If that fixes it, I was correct, and your NOMINMAX isn't being defined properly. (Add it as a project setting.)

You can also prevent macro expansion by: (std::numeric_limits<T>::max)().


On a side note, why not do std::numeric_limits<T>::min() instead of negating the max?

Community
  • 1
  • 1
GManNickG
  • 494,350
  • 52
  • 494
  • 543
  • @Adam: ...Except if T is a float or a double - then you'll want to make sure numeric_limits::min() is relevant. – Raphaël Saint-Pierre Apr 01 '10 at 15:42
  • Obviously, my comment applies to your first one :-) – Raphaël Saint-Pierre Apr 01 '10 at 15:43
  • 14
    Or, if you can't use `NOMINMAX` for some reason, you can prevent the macro expansion by parenthesizing the function name: `(std::numeric_limits::max)()`. This is very, very ugly, but can be necessary in some cases. – James McNellis Apr 01 '10 at 19:06
  • 3
    For twos-complement integers (which are pretty much all you get anymore), the minimum is one less than the negation of the maximum. So, I agree with your side note: why negate the max? – David Thornley Apr 01 '10 at 19:26
  • If you add the NOMINMAX to your header but it's included by some other file which has already included windows.h, the NOMINMAX won't work and max and min are already defined. That explains why the #undef min/max will sometimes work even when NOMINMAX doesn't. – ikku100 May 06 '16 at 15:36
  • 3
    The (std::numeric_limits::max)() worked for me just fine. A very handy post! – SpaceUser7448 Mar 28 '18 at 13:21
  • 4
    It's astounding how much trouble the windows.h definition of max/min causes. – danelliottster Jun 28 '19 at 16:53
  • Thanks for me writting `#define NOMINMAX #include ` just before including `` did the trick! – Hossein Sep 29 '20 at 14:17
  • 1
    @danelliottster Indeed. I cannot use a standard library function because of a stupid lowercase definition. – Burak Nov 20 '20 at 16:29
  • NOMINMAX does indeed solve this issue, however then some internal files like `gdiplustypes.h` won't compile. The solution is to update the SDK https://developercommunity2.visualstudio.com/t/GdiplusTypesh-does-not-compile-with-NOM/727770 – MasterHD Jan 12 '22 at 21:04
5

Looks like you need to:

#include <limits>

John Dibling
  • 99,718
  • 31
  • 186
  • 324
-1

I wrote a "test harness" with a trivial struct containing your method declaration (and nothing else), and #included <limits> and <vector>, and invoked (and thus instantiated) the method with T being int, and it compiled just fine, both on Visual Studio 2008 Express on Windows Vista and with GCC 4.2.4 on Linux 2.6.

I suggest trying to build only a minimal amount of code with the "problem" in it, and if that actually does build, add back in the rest of your project until it breaks, then you'll know what caused it.

John Zwinck
  • 239,568
  • 38
  • 324
  • 436