2009-12-15 94 views
55

Dòng này hoạt động chính xác trong một chương trình thử nghiệm nhỏ, nhưng trong chương trình mà tôi muốn nó, tôi nhận được khiếu nại biên dịch sau:cảnh báo C4003 và lỗi C2589 và C2059 trên: x = std :: numeric_limits <int> :: max();

#include <limits> 

x = std::numeric_limits<int>::max(); 

c:\...\x.cpp(192) : warning C4003: not enough actual parameters for macro 'max' 
c:\...\x.cpp(192) : error C2589: '(' : illegal token on right side of '::' 
c:\...\x.cpp(192) : error C2059: syntax error : '::' 

tôi nhận được kết quả tương tự với:

#include <limits> 
using namespace std; 

x = numeric_limits<int>::max(); 

Tại sao nó thấy tối đa là macro tối đa (a, b); ?

+0

Trong trường hợp của tôi, không có '-DNOMINMAX', tôi đã gặp phải lỗi trình biên dịch nội bộ. Thật thú vị khi xem cách Microsoft liên tục đấu tranh chống lại chính nó. –

Trả lời

74

này thường xảy ra khi bao gồm một tiêu đề Windows mà định nghĩa một min hoặc max vĩ mô. Nếu bạn đang sử dụng tiêu đề Windows, hãy đặt #define NOMINMAX vào mã của bạn hoặc xây dựng bằng công tắc trình biên dịch tương đương (ví dụ: sử dụng /DNOMINMAX cho Visual Studio).

Lưu ý rằng tòa nhà có NOMINMAX sẽ vô hiệu hóa việc sử dụng macro trong toàn bộ chương trình của bạn. Nếu bạn cần sử dụng các hoạt động min hoặc max, hãy sử dụng std::min() hoặc std::max() từ tiêu đề <algorithm>.

+0

Được rồi, tôi chỉ cần hỏi ... Tôi có thể có cả hai trong cùng một tệp không? x = std :: numeric_limits :: max(); // một số lệnh tiền xử lý phức tạp c = max (a, b); – Harvey

+0

@Harvey: Tôi đã chỉnh sửa câu trả lời của tôi để giải quyết việc sử dụng max() và macro max() trong một tệp. –

+0

Tôi sử dụng min() và max() trong các tệp khác trong dự án này và sử dụng các tiêu đề được biên dịch trước, nó bị tắt cho tất cả các tệp. #undef tối đa hoạt động cho trường hợp của tôi và chỉ có hiệu lực đối với phần còn lại của tệp. – Harvey

27

Một số tệp tiêu đề khác đang gây ô nhiễm không gian tên chung với macro tối đa. Bạn có thể khắc phục điều đó bằng cách undefining macro:

#undef max 
x = std::numeric_limits<int>::max(); 
+5

Không sửa lỗi theo cách này, bạn có thể ngăn không cho nó được xác định ngay từ đầu bằng 'NOMINMAX'. – GManNickG

61

Giải pháp khác là quấn tên hàm với dấu ngoặc đơn như sau: (std::numeric_limits<int>::max)(). Tương tự áp dụng cho std::max.

Không chắc là giải pháp tốt cho việc này ... NOMINMAX là IMO tốt hơn, nhưng điều này có thể là một tùy chọn trong một số trường hợp.

+1

Nhiều khi tôi ghét việc sử dụng các macro tối thiểu/tối đa toàn cầu, đôi khi thật khó để xóa chúng khỏi dự án hoàn toàn. Không bao giờ nghĩ về điều này như một giải pháp, vì vậy +1. – icabod

+6

Thật không may, các macro tối thiểu và tối đa được sử dụng rộng rãi trong SDK nền tảng Windows (ví dụ: GDI + GdiplusTypes.h). Vì vậy, bạn trả lời là tốt hơn sau đó xác định NOMINMAX. +1! – 23W

+0

Làm thế nào để gói giúp đỡ ở đây? thực sự bối rối, bạn có thể giải thích một chút không? – sami1592

3
#ifdef max 
#pragma push_macro("max") 
#undef max 
#define _restore_max_ 
#endif 

#include <limits> 

//... your stuff that uses limits 

#ifdef _restore_max_ 
#pragma pop_macro("max") 
#undef _restore_max_ 
#endif 
+0

@MattMcNabb Tôi đã thay đổi nó – dmjalund

0

định nghĩa của nó trong đối với tôi trong Visual Studio 2013 (định dạng cho khoảng cách tốt hơn ...) như sau:

static _Ty (max)() _THROW0() 
{ // return maximum value 
    return (FLT_MAX); 
} 

Vì vậy, tôi chỉ sử dụng FLT_MAX. :) Đây có thể không phải là một giải pháp phổ quát, nhưng nó hoạt động tốt trong trường hợp của tôi, vì vậy tôi nghĩ rằng tôi sẽ chia sẻ.

+1

Hãy cẩn thận, bạn (có thể) cần '#include ' để truy cập vào 'FLT_MAX' –