std::max, std::min错误

Why did I put parentheses around std::max? Because windows.h defines (among other things) a max and a min macro. If you include windows.h the above code will not compile. For example the following:
#include "windows.h"
#include <algorithm>

void foo() {
    int i = 5;
    int j = 7;
    int x = std::max(i,j);
}

Will produce the following error with Visual Studio C++ 2005:
1>test.cpp(7) : error C2589: '(' : illegal token on right side of '::'
1>test.cpp(7) : error C2143: syntax error : missing ';' before '::'

There are a number of ways to work around windows.h defining these two macros.

  • Use alternative names defined in windows.h.
    int x = _cpp_max(i,j);
    int y = _cpp_min(i,j);
    This is not portable; only works on Windows.

  • Define NOMINMAX before including windows.h. This might break existing code that assumes NOMINMAX is not defined.

  • Don't use std::min and std::max. Instead use the tertiary operator like so:
    int x = i > j ? i : j; // max(i,j)
    int y = i < j ? i : j; // min(i,j)
    This is portable but not as readable and more error prone.

  • Use using statements to make the code portable:
    using std::min;
    using std::max;
    int x = max(i,j);
    int y = min(i,j);
    This works but requires two more lines of code. You could also just use 'using namespace std;' but that might pull in more than you want.

  • Use std::min<int> and std::max<int>
    int x = std::max<int>(i,j);
    int y = std::min<int>(i,j);
    This requires you to specify the type. However in some cases this actually helps. For example:
    int i = 5;
    unsigned int j = 7;
    int x = (std::max)(i,j);
    int y = (std::min)(i,j);
    Note the 'unsigned'. Generates the following errors:
    1>test.cpp(7) : error C2780: 'const _Ty &std::max(const _Ty &,const _Ty &,_Pr)' : 
    expects 3 arguments - 2 provided
    1>        c:\program files\microsoft visual studio 8\vc\include\xutility(3190) :
    see declaration of 'std::max'
    1>test.cpp(7) : error C2782: 'const _Ty &std::max(const _Ty &,const _Ty &)' :
    template parameter '_Ty' is ambiguous
    1>        c:\program files\microsoft visual studio 8\vc\include\xutility(3182) :
    see declaration of 'std::max'
    1>        could be 'unsigned int'
    1>        or 'int'
    By explicitly specifying type via <int> you remove the ambiguity.

  • Use (std::min) and (std::max)
    int i = 5;
    int j = 7;
    int x = (std::max)(i,j);
    int y = (std::min)(i,j);
    This works (as does the std::max<int>) because the C++ preprocessor requires '(' as the next preprocessing token following the macro name to preform the macro expansion.
From: http://heifner.blogspot.jp/2008/02/stdmin-and-stdmax.html
### C++ 中 `std::max` 和 `std::min` 运行时错误的原因及解决方法 在 C++ 中,`std::max` 和 `std::min` 是用于比较两个值或一组值并返回最大值或最小值的函数。如果在使用这些函数时遇到运行时错误,通常可能是由于以下原因导致的: #### 1. 类型不匹配 `std::max` 和 `std::min` 的参数类型必须一致或可以隐式转换为相同的类型。如果提供的参数类型无法匹配,则可能导致编译错误或未定义行为。 例如,以下代码会导致错误: ```cpp int a = 5; double b = 3.2; auto result = std::max(a, b); // 编译器可能无法正确推导类型 ``` 解决方法是显式指定模板参数类型,或者确保参数类型一致[^3]: ```cpp int a = 5; double b = 3.2; auto result = std::max<double>(a, b); // 显式指定类型为 double ``` #### 2. 自定义类型未定义比较操作 如果对自定义类型使用 `std::max` 或 `std::min`,但该类型未重载 `<` 或 `>` 操作符,则会导致编译错误。 例如: ```cpp struct Point { int x, y; }; Point p1{1, 2}, p2{3, 4}; auto result = std::max(p1, p2); // 错误:Point 类型未定义比较操作 ``` 解决方法是为自定义类型重载比较操作符,或者提供一个自定义比较函数作为第三个参数: ```cpp struct Point { int x, y; }; bool operator<(const Point& lhs, const Point& rhs) { return lhs.x < rhs.x || (lhs.x == rhs.x && lhs.y < rhs.y); } Point p1{1, 2}, p2{3, 4}; auto result = std::max(p1, p2); // 正确:重载了 < 操作符 ``` #### 3. 使用空的初始化列表 当使用 `std::initializer_list` 版本的 `std::max` 或 `std::min` 时,如果提供的列表为空,则会导致未定义行为。 例如: ```cpp auto result = std::max({}); // 错误:初始化列表为空 ``` 解决方法是确保初始化列表中至少包含一个元素: ```cpp auto result = std::max({1, 2, 3}); // 正确:包含多个元素 ``` #### 4. 线程安全问题 虽然 `std::max` 和 `std::min` 本身是线程安全的,但如果在多线程环境中操作共享数据且未进行同步,则可能导致运行时错误。 例如: ```cpp #include <thread> #include <iostream> int main() { int a = 5, b = 3; std::thread t1([&]() { std::cout << std::max(a, b) << '\n'; }); std::thread t2([&]() { a = -1; }); // 修改共享变量 a t1.join(); t2.join(); } ``` 解决方法是通过互斥锁或其他同步机制保护共享数据[^4]: ```cpp #include <thread> #include <iostream> #include <mutex> std::mutex mtx; int main() { int a = 5, b = 3; std::thread t1([&]() { std::lock_guard<std::mutex> lock(mtx); std::cout << std::max(a, b) << '\n'; }); std::thread t2([&]() { std::lock_guard<std::mutex> lock(mtx); a = -1; }); t1.join(); t2.join(); } ``` #### 5. 非法内存访问 如果传递给 `std::max` 或 `std::min` 的参数涉及非法内存访问(如空指针解引用),则可能导致运行时错误。 例如: ```cpp int* a = nullptr; int b = 3; auto result = std::max(*a, b); // 错误:解引用空指针 ``` 解决方法是确保所有参数都有效且不会引发非法内存访问: ```cpp int* a = new int(5); int b = 3; auto result = std::max(*a, b); // 正确:避免空指针解引用 delete a; ``` ### 示例代码 以下是一个综合示例,展示如何正确使用 `std::max` 和 `std::min` 并避免常见错误: ```cpp #include <iostream> #include <algorithm> struct Point { int x, y; }; bool operator<(const Point& lhs, const Point& rhs) { return lhs.x < rhs.x || (lhs.x == rhs.x && lhs.y < rhs.y); } int main() { int a = 5, b = 3; auto max_val = std::max(a, b); // 正确:基本类型比较 std::cout << "Max value: " << max_val << '\n'; Point p1{1, 2}, p2{3, 4}; auto max_point = std::max(p1, p2); // 正确:重载了 < 操作符 std::cout << "Max point: (" << max_point.x << ", " << max_point.y << ")\n"; auto min_max = std::minmax({1, 2, 3, 4, 5}); // 正确:初始化列表非空 std::cout << "Min value: " << min_max.first << ", Max value: " << min_max.second << '\n'; } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值