C++ 标准库函数与宏定义的名字冲突
转至 http://blog.csdn.net/rnamatrix/article/details/5765462
今天在使用limits中的numeric_limits类模板函数max和min时,编译出现了一个错误:
- error C2589: '(' : illegal token on right side of '::'
error C2589: '(' : illegal token on right side of '::'
百思不得其解,后来突然想到max和min很有可能已经被定义成了宏,于是查看包进来的头文件,发现蹊跷肯定在<windows.h>中:
windows.h包括了windef.h头文件,在windef.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 */
#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 */
所以这里的max和min的宏定义就与标准模板库中的numeric_limits<*>::max/min的定义发生了冲突,加入#define NOMINMAX问题就解决了。
(注意宏的作用域都是全局(scope-less evil)的)
进一步去google了一下关于类似的max/min宏的定义还发生在哪些常用的头文件中。
这里指出,max/min的宏定义还出现在了stdlib.h和minmax.h头文件中。
在stdlib.h中:
- #if !__STDC__
- #ifndef _POSIX_
- /* Non-ANSI names for compatibility */
- #ifndef __cplusplus
- #define max(a,b) (((a) > (b)) ? (a) : (b))
- #define min(a,b) (((a) < (b)) ? (a) : (b))
- #endif
- ...
#if !__STDC__ #ifndef _POSIX_ /* Non-ANSI names for compatibility */ #ifndef __cplusplus #define max(a,b) (((a) > (b)) ? (a) : (b)) #define min(a,b) (((a) < (b)) ? (a) : (b)) #endif ...
一般ANSI C中使用__max和__min宏,max和min只是在非标准C中才会定义,所以一般使用标准C时,包括了stdlib.h头文件不会发生和max/min宏的冲突。
而minmax.h头文件一般只是在你想使用max/min宏时才会被包括进来。
并且,在网上还发现了此问题的另外一个解决方式:
- (std::min)(x, y);
- (std::max)(x, y);
- (std::numeric_limits<T>::min)();
- (std::numeric_limits<T>::max)();
(std::min)(x, y); (std::max)(x, y); (std::numeric_limits<T>::min)(); (std::numeric_limits<T>::max)();
这样把函数名用括号括起来了,max/min不再被当作带参数的宏去替换了,因此能够避免冲突。
当用户自己定义的类型的成员函数与全局的宏定义发生冲突时,都可以采用这种解决方法。
- template <typename T, int Size>
- struct Series
- {
- T min() { return *(std::min_element(s, s + Size); }
- T& operator[](int index) { return s[index]; }
- private:
- T s[Size];
- };
- Series<int, 3> s;
- s[0] = 2;
- s[1] = 3;
- s[2] = 1;
- int m = (s.min)(); // long way, but here is the trick
template <typename T, int Size> struct Series { T min() { return *(std::min_element(s, s + Size); } T& operator[](int index) { return s[index]; } private: T s[Size]; }; Series<int, 3> s; s[0] = 2; s[1] = 3; s[2] = 1; int m = (s.min)(); // long way, but here is the trick
只是,这种方式可能会面临一些负面影响:
这种方式下不能使用ADL(Argument Depended Name Lookup)了,所以成员函数前必须加上类名或者名字空间域名,也就是必须是fully qualified。
C++ 标准库函数与宏定义的名字冲突相关推荐
- 【C进阶】之宏定义的扩展
宏定义扩展在底层经常看到 1. 常量宏定义 2. 定义宏函数 3. 宏定义和#号结合 4. 宏定义和两个#结合 5. 宏定义和do...while()的结合 6. #ifdef...#else...# ...
- C语言便于调试的宏定义 __FILE__、__FUNCTION__、__LINE__、__VA_ARGS__ 参数使用
__FILE__.__FUNCTION__.__LINE__ 这几个宏定义从名字就可以看出功能: __FILE__:宏在预编译时会替换成当前的源文件名,字符串类型. __FUNCTION__:宏在预编 ...
- 【GCC编译优化系列】宏定义名称与函数同名是一种什么骚操作?
作者简介 *架构师李肯(全网同名)**,一个专注于嵌入式IoT领域的架构师.有着近10年的嵌入式一线开发经验,深耕IoT领域多年,熟知IoT领域的业务发展,深度掌握IoT领域的相关技术栈,包括但不限于 ...
- abs int 宏定义_在标准C中,预处理语句,特别是宏定义中,常常出现'#'和'##'符号,#字符串创建运算符#...
我看<U N I X环境高级编程>第七章时看到这么条宏定义: #define doit(name) pr_limits(#name, name) 这里第二个#号是什 ...
- 【C++】C++标准中定义的名字和标识符
标识符 identifier C++中标识符有明确的定义,对保留的标识符也有明确的说明. 标识符是任意长的字母/字符,数字,下划线的序列.但是有效标识符必须以非数字起头,且是大小写敏感的,标识符中的每 ...
- 国际绝对音名十二等律标准对照音高频率的宏定义(32位无符号整型精度、十二等律体系、A4=440.01000Hz)
国际绝对音名十二等律标准对照音高频率的宏定义(32位无符号整型精度.十二等律体系.A4=440.01000Hz) 代码如下: #ifndef __PITCH_H__ #define __PITCH_H ...
- 【Kernel学习】基础篇——01一些标准宏定义和文件include关系
先从最简单的宏定义学习学习:熟悉一下内核中的一些基本类型的定义,和代码风格 今天我们从stddef.h文件开始看: 1.include/linux/stddef.h 1 #ifndef _LINUX_ ...
- c++fabs函数_C语言中常用的标准库函数有哪些?
点击上方蓝色字关注我们! 本文转自网络,版权归原作者所有. 标准头文件包括: 一.标准定义() 文件里包含了标准库的一些常用定义,无论我们包含哪个标准头文件,都会被自动包含进来. 这个文件里定义: 类 ...
- 6、宏定义与预处理、函数与函数库
C语言预处理理论 由源码到可执行程序的过程 源码.c->(编译)->elf可执行程序 源码.c->(编译)->目标文件.o->(链接)->elf可执行程序 源码.c ...
最新文章
- python输入列表方法_Python用input输入列表的方法
- RecycleView 嵌套 RecycleView 导致自动滚动
- 模拟video播放器
- ITK:过滤图像FilterImage
- 让文本输入框只能输入数字
- Apache cxf JaxRs基本应用
- 【Android 12 AOSP学习】Android 12源码下载编译
- android 键盘 横屏 边框,Android横屏时软键盘全屏问题
- 数电课设交通灯控制器
- 云计算是一种商业模式
- are in unnamed module of loader ‘app‘)“ }
- 开涛老师对Java的全部理解,很透彻。
- 数字转中文(大写,小写)数字,金额
- C语言入门(四):有关逻辑的运算符和表达式
- 关于图像分割的预处理 transform
- c语言实现表白代码,给你现在(未来)的那个她(他)准备一个吧
- 上午还在改bug,下午就被离职!年底大裁员寒潮来袭……
- 小白mybatis学习(三)输出结果配置
- cst是什么时间(Cst是什么检查)
- 智能照明控制系统的设计和应用