【C++】灵活使用C/C++宏定义

原创 2016年05月31日 20:36:45

灵活使用C/C++宏定义

 #define宏定义在C语言中有广泛使用。对于C++语言,《Effective C++》第二章告诉我们,在C++中尽量用const、enum、inline替换#define,可以避免很多陷阱。其中const用于定义常量,enum用于定义枚举,inline用于定义内联函数。
 尽管《Effective C++》第二章指出#define宏定义的诸多陷阱,这不代表作者不希望我们使用#define。#define的作用是,在预编译阶段,编译器将#define定义的代码段替换到使用相应宏定义的位置上去,相当于直接将代码替换宏,如果宏定义是安全的、简单的,那么#define宏定义会有很大的作用。很多著名C++第三方库使用了大量的宏定义,可以说明这一点。
 来看看Eigen矩阵库。Eigen是基于模板的C++开源矩阵库,使用或者支持Eigen的知名项目有Google的TensorFlow、Point Cloud Library、OpenCV等。Eigen运用了大量的模板,为了管理这些模板,Eigen使用了大量的宏,我摘要一段如下,其中##符号表示连接两个字符串:

#define EIGEN_MAKE_TYPEDEFS(Type, TypeSuffix, Size, SizeSuffix)   \
typedef Matrix<Type, Size, Size> Matrix##SizeSuffix##TypeSuffix;  \
...
#define EIGEN_MAKE_TYPEDEFS_ALL_SIZES(Type, TypeSuffix) \
EIGEN_MAKE_TYPEDEFS(Type, TypeSuffix, 2, 2) \
EIGEN_MAKE_TYPEDEFS(Type, TypeSuffix, 3, 3) \
...
EIGEN_MAKE_TYPEDEFS_ALL_SIZES(int,                  i)
EIGEN_MAKE_TYPEDEFS_ALL_SIZES(float,                f)
...

上述写出的宏定义代码,定义了

Matrix2i<->Matrix<int, 2, 2>;
Matrix2f<->Matrix<float, 2, 2>;
Matrix3i<->Matrix<int, 3, 3>;
Matrix3f<->Matrix<float, 3, 3>

四个数据类型。用上述宏定义的方法可以用很少的代码,扩展定义更多的类型。
 再来看看VTK。我展示VTK用于定义set/get函数的代码:

//宏定义
#define vtkSetMacro(name,type) \
virtual void Set##name (type _arg) \
  { \
  vtkDebugMacro(<< this->GetClassName() << " (" << this << "): setting " #name " to " << _arg); \
  if (this->name != _arg) \
    { \
    this->name = _arg; \
    this->Modified(); \
    } \
  } 
#define vtkGetMacro(name,type) \
virtual type Get##name () { \
  vtkDebugMacro(<< this->GetClassName() << " (" << this << "): returning " << #name " of " << this->name ); \
  return this->name; \
  } 
  //定义set/get函数
  vtkSetMacro(CurrentCursor,int);
  vtkGetMacro(CurrentCursor,int);

上述代码很方便地定义了
virtual void SetCurrentCursor(int _arg);
virtual int GetCurrentCursor();

这就免得我再去手写一大堆代码。可见宏定义用于定义是很方便的。
另外我附上如果根据操作系统宏来定义不同数据的示例代码:
#ifdef _WIN32
#define SMARTPOINTER(type) std::tr1::shared_ptr<type> SP;
#else
#define SMARTPOINTER(type) std::shared_ptr<type> SP;
#endif
//下面的代码编译错误
//#define SMARTPOINTER(type) \
//#ifdef _WIN32 #define std::tr1::shared_ptr<type> SPA; \
//#else #define std::shared_ptr<type> SPA; #endif

这里看出,如果#define内部还有复杂的宏命令,则编译器很难给出正确的编译结果。尤其是使用旧版本编译器,必须要注意宏定义不能过于复杂。

版权声明:本文为博主原创文章,未经博主允许不得转载。 举报

相关文章推荐

C++自定义数据类型之枚举

枚举        如果一个变量你需要几种可能存在的值,那么就可以被定义成为枚举类型。之所以叫枚举就是说将变量或者叫对象可能存在的情况也可以说是可能的值一一例举出来。      &...

深入理解C++枚举类型enum

参考:http://blog.csdn.net/weiwenhp/article/details/8476767 http://blog.csdn.net/mtfxabc/article/detail...

精选:深入理解 Docker 内部原理及网络配置

网络绝对是任何系统的核心,对于容器而言也是如此。Docker 作为目前最火的轻量级容器技术,有很多令人称道的功能,如 Docker 的镜像管理。然而,Docker的网络一直以来都比较薄弱,所以我们有必要深入了解Docker的网络知识,以满足更高的网络需求。

【C++】灵活使用C/C++宏定义

灵活使用宏定义 #define宏定义在C语言中有广泛使用。对于C++语言,《Effective C++》第二章告诉我们,在C++中尽量用const、enum、inline替换#define,可以避免很...

C/C++ 宏定义

目录(?)[-] 简单宏定义带参数的宏运算符运算符宏的通用属性宏定义中圆括号创建较长的宏 较长的宏中的逗号运算符宏定义中的do-while循环do 空操作的定义 预定义宏C语言中常用的宏 ...

[c/c++]宏定义,#,##

# —— 字符串 ##——连接两个参数 #include iostream> using namespace std; #define TEST(pid) (cout #defi...

C/C++ 宏定义 # ##

一、C/C++ 宏定义 # Stringizing Operator 数字符号或“字符串化”运算符 (#) 将宏参数转换为字符串而不扩展参数定义。 它只用于采用参数的宏。 如果它在宏定义中位于形参之...

[c/c++]宏定义,#,##

/c++]宏定义,#,## # —— 字符串 ##——连接两个参数 #include using namespace std; #define TEST(pid) (cout #def...

C/C++常用宏定义

下面列举一些成熟软件中常用得宏定义 1,防止一个头文件被重复包含  #ifndef COMDEF_H  #define COMDEF_H  //头文件内容 ... #endif  ...

C++宏定义

C++ 宏定义将一个标识符定义为一个字符串,源程序中的该标识符均以指定的字符串来代替。前面已经说过,预处理命令不同于一般C++语句。因此预处理命令后通常不加分号。这并不是说所有的预处理命令后都不能有分...

C++宏定义

一、define中的三个特殊符号:#,##,#@#define Conn(x,y) x##y #define ToChar(x) #@x #define ToString(x) #x(1)x##y表示...
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)