Overcoming problem with std::min, std::max, #define NOMINMAX
-
Hello, I'm writing/maintaining an MFC app that makes extensive use of a database API that uses std::min and std::max, which is used in most of the application's translation units. Therefore, it makes sense to include the APIs convenience header (which in turn includes everything) in stdafx.h. The API requires that I #define NOMINMAX, so that the C++ std library's min and max function templates are used, rather than MS's legacy min and max macros. I have #define'd NOMINMAX in stdaxf.h . This worked fine for a long time. However, I recently installed the MFC 2008 feature pack. I must now #include afxcontrolbars.h. However, this header has inline functions that are dependent on the min and max macros which are now missing. I tried to "#include algorithm; using std::min; using std::max;" immediately before I include afxcontrolbars.h, so that std::min and std::max would be used as drop in replacements for the macros (this has worked in other areas in the past) but stdafx.cpp still doesn't build:
1>Compiling...
1>stdafx.cpp
1>c:\program files\microsoft visual studio 9.0\vc\atlmfc\include\afxtoolbar.h(166) : error C2782: 'const _Ty &std::max(const _Ty &,const _Ty &)' : template parameter '_Ty' is ambiguous
1> c:\program files\microsoft visual studio 9.0\vc\include\xutility(3356) : see declaration of 'std::max'
1> could be 'LONG'
1> or 'int'
1>c:\program files\microsoft visual studio 9.0\vc\atlmfc\include\afxtoolbar.h(166) : error C2780: 'const _Ty &std::max(const _Ty &,const _Ty &,_Pr)' : expects 3 arguments - 2 provided
1> c:\program files\microsoft visual studio 9.0\vc\include\xutility(3364) : see declaration of 'std::max'
1>c:\program files\microsoft visual studio 9.0\vc\atlmfc\include\afxmenubar.h(161) : error C2782: 'const _Ty &std::max(const _Ty &,const _Ty &)' : template parameter '_Ty' is ambiguous
1> c:\program files\microsoft visual studio 9.0\vc\include\xutility(3356) : see declaration of 'std::max'
1> could be 'LONG'
1> or 'int'
1>c:\program files\microsoft visual studio 9.0\vc\atlmfc\include\afxmenubar.h(161) : error C2780: 'const _Ty &std::max(const _Ty &,const _Ty &,_Pr)' : expects 3 arguments - 2 provided
1> c:\program files\microsoft visual studio 9.0\vc\include\xutility(3364) : see declaration of 'std::max'
1>c:\program files\microsoft visual studio 9.0\vc\atlmfc\include\afxdesktopalertwnd.h(81) : error C2782: 'const _T -
Hello, I'm writing/maintaining an MFC app that makes extensive use of a database API that uses std::min and std::max, which is used in most of the application's translation units. Therefore, it makes sense to include the APIs convenience header (which in turn includes everything) in stdafx.h. The API requires that I #define NOMINMAX, so that the C++ std library's min and max function templates are used, rather than MS's legacy min and max macros. I have #define'd NOMINMAX in stdaxf.h . This worked fine for a long time. However, I recently installed the MFC 2008 feature pack. I must now #include afxcontrolbars.h. However, this header has inline functions that are dependent on the min and max macros which are now missing. I tried to "#include algorithm; using std::min; using std::max;" immediately before I include afxcontrolbars.h, so that std::min and std::max would be used as drop in replacements for the macros (this has worked in other areas in the past) but stdafx.cpp still doesn't build:
1>Compiling...
1>stdafx.cpp
1>c:\program files\microsoft visual studio 9.0\vc\atlmfc\include\afxtoolbar.h(166) : error C2782: 'const _Ty &std::max(const _Ty &,const _Ty &)' : template parameter '_Ty' is ambiguous
1> c:\program files\microsoft visual studio 9.0\vc\include\xutility(3356) : see declaration of 'std::max'
1> could be 'LONG'
1> or 'int'
1>c:\program files\microsoft visual studio 9.0\vc\atlmfc\include\afxtoolbar.h(166) : error C2780: 'const _Ty &std::max(const _Ty &,const _Ty &,_Pr)' : expects 3 arguments - 2 provided
1> c:\program files\microsoft visual studio 9.0\vc\include\xutility(3364) : see declaration of 'std::max'
1>c:\program files\microsoft visual studio 9.0\vc\atlmfc\include\afxmenubar.h(161) : error C2782: 'const _Ty &std::max(const _Ty &,const _Ty &)' : template parameter '_Ty' is ambiguous
1> c:\program files\microsoft visual studio 9.0\vc\include\xutility(3356) : see declaration of 'std::max'
1> could be 'LONG'
1> or 'int'
1>c:\program files\microsoft visual studio 9.0\vc\atlmfc\include\afxmenubar.h(161) : error C2780: 'const _Ty &std::max(const _Ty &,const _Ty &,_Pr)' : expects 3 arguments - 2 provided
1> c:\program files\microsoft visual studio 9.0\vc\include\xutility(3364) : see declaration of 'std::max'
1>c:\program files\microsoft visual studio 9.0\vc\atlmfc\include\afxdesktopalertwnd.h(81) : error C2782: 'const _TCan you do something like this:
#undef NOMINMAX
#include "afxcontrolbars.h"
#define NOMINMAX -
Can you do something like this:
#undef NOMINMAX
#include "afxcontrolbars.h"
#define NOMINMAXRichard, Thanks for that. I should have mentioned that that was the first thing that I tried. The result was exactly the same compiler errors as when I don't #undef:
1>------ Build started: Project: Lustre, Configuration: Debug Win32 ------
1>Compiling...
1>stdafx.cpp
1>c:\program files\microsoft sdks\windows\v6.1\include\gdiplustypes.h(471) : error C3861: 'min': identifier not found
1>c:\program files\microsoft sdks\windows\v6.1\include\gdiplustypes.h(472) : error C3861: 'min': identifier not found
1>c:\program files\microsoft sdks\windows\v6.1\include\gdiplustypes.h(473) : error C3861: 'max': identifier not found
1>c:\program files\microsoft sdks\windows\v6.1\include\gdiplustypes.h(474) : error C3861: 'max': identifier not found
1>c:\program files\microsoft sdks\windows\v6.1\include\gdiplustypes.h(495) : error C3861: 'max': identifier not found
1>c:\program files\microsoft sdks\windows\v6.1\include\gdiplustypes.h(496) : error C3861: 'max': identifier not found
1>c:\program files\microsoft sdks\windows\v6.1\include\gdiplustypes.h(497) : error C3861: 'min': identifier not foundI guess that exactly the same error message appears because stdafx.h is included in some header that is included somewhere, directly or indirectly, in gdiplustypes.h et al, which are included in afxcontrolbars.h. Regards, Sternocera
-
Can you do something like this:
#undef NOMINMAX
#include "afxcontrolbars.h"
#define NOMINMAXI've come up with this unfortunate hack:
#define NOMINMAX
#ifndef max
#define max(a,b) (((a) > (b)) ? (a) : (b))
#endif#ifndef min
#define min(a,b) (((a) < (b)) ? (a) : (b))
#endif
#include <afxcontrolbars.h>
#undef max
#undef min
// ...contine to use std::mix, std::max from here onWhen I undefined NOMINMAX, min and max were already defined, so it didn't matter. So, I've simply defined min and max just as they are defined from within WinDef.h . Regards, Sternocera
-
I've come up with this unfortunate hack:
#define NOMINMAX
#ifndef max
#define max(a,b) (((a) > (b)) ? (a) : (b))
#endif#ifndef min
#define min(a,b) (((a) < (b)) ? (a) : (b))
#endif
#include <afxcontrolbars.h>
#undef max
#undef min
// ...contine to use std::mix, std::max from here onWhen I undefined NOMINMAX, min and max were already defined, so it didn't matter. So, I've simply defined min and max just as they are defined from within WinDef.h . Regards, Sternocera
Brilliant! Not sure I would have thought of that...... :-O
-
Hello, I'm writing/maintaining an MFC app that makes extensive use of a database API that uses std::min and std::max, which is used in most of the application's translation units. Therefore, it makes sense to include the APIs convenience header (which in turn includes everything) in stdafx.h. The API requires that I #define NOMINMAX, so that the C++ std library's min and max function templates are used, rather than MS's legacy min and max macros. I have #define'd NOMINMAX in stdaxf.h . This worked fine for a long time. However, I recently installed the MFC 2008 feature pack. I must now #include afxcontrolbars.h. However, this header has inline functions that are dependent on the min and max macros which are now missing. I tried to "#include algorithm; using std::min; using std::max;" immediately before I include afxcontrolbars.h, so that std::min and std::max would be used as drop in replacements for the macros (this has worked in other areas in the past) but stdafx.cpp still doesn't build:
1>Compiling...
1>stdafx.cpp
1>c:\program files\microsoft visual studio 9.0\vc\atlmfc\include\afxtoolbar.h(166) : error C2782: 'const _Ty &std::max(const _Ty &,const _Ty &)' : template parameter '_Ty' is ambiguous
1> c:\program files\microsoft visual studio 9.0\vc\include\xutility(3356) : see declaration of 'std::max'
1> could be 'LONG'
1> or 'int'
1>c:\program files\microsoft visual studio 9.0\vc\atlmfc\include\afxtoolbar.h(166) : error C2780: 'const _Ty &std::max(const _Ty &,const _Ty &,_Pr)' : expects 3 arguments - 2 provided
1> c:\program files\microsoft visual studio 9.0\vc\include\xutility(3364) : see declaration of 'std::max'
1>c:\program files\microsoft visual studio 9.0\vc\atlmfc\include\afxmenubar.h(161) : error C2782: 'const _Ty &std::max(const _Ty &,const _Ty &)' : template parameter '_Ty' is ambiguous
1> c:\program files\microsoft visual studio 9.0\vc\include\xutility(3356) : see declaration of 'std::max'
1> could be 'LONG'
1> or 'int'
1>c:\program files\microsoft visual studio 9.0\vc\atlmfc\include\afxmenubar.h(161) : error C2780: 'const _Ty &std::max(const _Ty &,const _Ty &,_Pr)' : expects 3 arguments - 2 provided
1> c:\program files\microsoft visual studio 9.0\vc\include\xutility(3364) : see declaration of 'std::max'
1>c:\program files\microsoft visual studio 9.0\vc\atlmfc\include\afxdesktopalertwnd.h(81) : error C2782: 'const _TWhile your hack (mentioned in another post) doesn't seem too egregious to me, another possible solution could be to add more template function overloads - I'm just showing max here:
namespace std {
template<class A>
bool max(int const& a, A const& b) { return a>b?a:b; }template<class A>
bool max(A const& a, int const& b) { return a>b?a:b; }
}These should take care of the cases in your header that aren't compiling with the STL min function, as (if you read the error messages) one of the types involved is always int.
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
-
While your hack (mentioned in another post) doesn't seem too egregious to me, another possible solution could be to add more template function overloads - I'm just showing max here:
namespace std {
template<class A>
bool max(int const& a, A const& b) { return a>b?a:b; }template<class A>
bool max(A const& a, int const& b) { return a>b?a:b; }
}These should take care of the cases in your header that aren't compiling with the STL min function, as (if you read the error messages) one of the types involved is always int.
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
Hi just include
#include #include
to your source file and this should be easily solved
-
Hi just include
#include #include
to your source file and this should be easily solved
No. Notice I suggested defining partially specialised templates, not the ones in - this is because the OPs problem was because of a template parameter deduction failure due to a mix of LONG and int parameters being passed to min/max.
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p