minmax.cpp): #include <algorithm>
int main() {
  int a = std::min(10, 20);
  return 0;
}windows.h: #include <algorithm>
#include <windows.h>
int main() {
  int a = std::min(10, 20);
  return 0;
}minmax.cpp
minmax.cpp(4) : error C2589: '(' : illegal token on right side of '::'
minmax.cpp(4) : error C2059: syntax error : '::'ПостановкаОчевидно, проблема в том, что кто-то переопределил значение слова#include <windows.h>до#include <algorithm>проблемы не решает.
min. Запустим препроцессор и проверим догадку: cl /P minmax.cppminmap.i): #line 7 "minmax.cpp"
int main() {
  int a = std::(((10) < (20)) ? (10) : (20));
  return 0;
}Покопавшись в заголовочных файлах Windows SDK, в файле WinDef.h, который косвенно подключается через windows.h, я нашел корень зла: 
#ifndef NOMINMAX
#ifndef max
#define max(a,b)            (((a) > (b)) ? (a) : (b))
#endif
#ifndef min
#define min(a,b)            (((a) < (b)) ? (a) : (b))
#endif
#endif  /* NOMINMAX */NOMINMAX, тем самым заблокировать определение min и max: #define NOMINMAX
#include <algorithm>
#include <windows.h>
int main() {
  int a = std::min(10, 20);
  return 0;
}Забавно, что в Cygwin и CodeGear/Borland исходный пример компилируется без проблем. В борландовой версии windows.h я нашел вот такой фрагмент: 
#if defined(__BORLANDC__)
...
#    if defined(__cplusplus)
#       define NOMINMAX              /* for WINDEF.H */
...
#    endif
...
#endif /* __BORLANDC__ */Вывод: Порой промежуточные результаты работы препроцессора являются крайне полезной информацией.
На всякий случай напомню, как его запускать для перечисленных мной компиляторов: 
Visual Studio:
cl /P имя_исходника.cppcpp32 имя_исходника.cppcpp имя_исходника.cpp-D и -U) и пути для поиска включаемых файлов (обычно это флаг -I).Другие посты по теме:
 
 
 
 
 Сообщения
Сообщения
 
 
Тут есть один интересный тонкий момент - бороться с этим без #define NOMINMAX/#undef max можно вот так - (std::max)(a, b). Подсмотрено кажется где-то в бусте.
ОтветитьУдалитьArseny Kapoulkine: Действительно, если написать(std::max)(a, b), то макроподстановка не происходит, и все работает.
ОтветитьУдалитьСпасибо.