我一直在试图写一个#define类似函数的宏,但是我被卡住了.这是我正在使用的示例:
#include <iostream>
#define pMAKE(x,y,z,dest)\
(dest).(x) = (x);\
(dest).(y) = (y);\
(dest).(z) = (z);
struct pt {
double x, y, z;
};
int main() {
pt p;
pMAKE(0,1,2,p);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我得到的错误:
A.cpp: In function ‘int main()’:
A.cpp:13: error: expected unqualified-id before ‘(’ token
A.cpp:13: error: expected unqualified-id before ‘(’ token
A.cpp:13: error: expected unqualified-id before ‘(’ token
Run Code Online (Sandbox Code Playgroud)
这些错误意味着什么,为什么我会得到它们?我设法得到以下工作方式,但我真的很幸运,我真的不明白发生了什么.
#define pMAKE(X,Y,Z,dest)\
dest.x = (X);\
dest.y = (Y);\
dest.z = (Z);
Run Code Online (Sandbox Code Playgroud)
我感谢你的每一点帮助!
使用宏的第一个版本,pMAKE(0,1,2,p);展开到
p.0 = 0;
p.1 = 1;
p.2 = 2;;
Run Code Online (Sandbox Code Playgroud)
换句话说,你已经到预处理远参考x,y,z的成员pt使用x,y,z作为两个变量名(在任务的左侧)和标签由预处理器来代替(在右面分配).
(如Konrad Rudolph所述)遗憾的是,您的宏仍有另一个严重错误.考虑表单的代码
pt p;
if (foo)
pMAKE(0,1,2,p);
Run Code Online (Sandbox Code Playgroud)
扩展到
pt p;
if (foo)
p.x = 0;
p.y = 1; // happens regardless of 'foo' test
p.z = 2;; // happens regardless of 'foo' test
Run Code Online (Sandbox Code Playgroud)
您可以通过将宏更改为来解决此问题(并摆脱烦人的额外分号)
#define pMAKE(X,Y,Z,dest)\
do { \
(dest).x = (X);\
(dest).y = (Y);\
(dest).z = (Z);\
} while (0)
Run Code Online (Sandbox Code Playgroud)
struct pt {
double x, y, z;
pt(double _x, double _y, double _z) : x(_x), y(_y), z(_z) { }
};
pt p (0.0, 1.0, 2.0);
Run Code Online (Sandbox Code Playgroud)
不要在C++中使用宏.
或者,正如@potatoswatter建议的那样,在C++ 11中立即完成它
struct pt { double x, y, z; };
pt p = { 0.0, 1.0, 2.0 };
Run Code Online (Sandbox Code Playgroud)