我想写一个简单的宏函数。因为这个宏在许多地方被不同的普通 c++ 函数使用,所以我遇到了变量范围问题。请问有没有快速解决的办法?非常感谢。
如您在附加代码中所见,根据宏是否在函数中首次调用,我想声明或重用变量ptrCandidate
。请注意,变量范围在函数中,而不是在文件或翻译单元中。换句话说,每次第一次在新函数中调用宏时,我都想要顶部宏。在同一个函数中,如果再次调用宏,我需要底部的宏。
#define EXPECT_MY_CLASS_EQ(expectedStr, candidateStr) \
auto ptrCandidate = parseAndGetPtr(candidateStr); \
doWork(ptrCandidate); \
EXPECT_EQ(expectedStr, convertToString(ptrCandidate));
#define EXPECT_MY_CLASS_EQ(expectedStr, candidateStr) \
ptrCandidate = parseAndGetPtr(candidateStr); \
doWork(ptrCandidate); \
EXPECT_EQ(expectedStr, convertToString(ptrCandidate));
void foo(){
EXPECT_MY_CLASS_EQ("123","abcd")
}
void bar(){
EXPECT_MY_CLASS_EQ("111","aabb")
EXPECT_MY_CLASS_EQ("222","ccdd")
}
void foo(){
auto ptrCandidate = parseAndGetPtr("abcd");
doWork(ptrCandidate);
EXPECT_EQ("123", convertToString(ptrCandidate));
}
void bar(){
auto ptrCandidate = parseAndGetPtr("aabb");
doWork(ptrCandidate);
EXPECT_EQ("111", convertToString(ptrCandidate));
/* auto */ ptrCandidate = parseAndGetPtr("ccdd");
doWork(ptrCandidate);
EXPECT_EQ("222", convertToString(ptrCandidate));
}
最佳答案
如另一个答案所示,在这种情况下您不需要宏。
不过一般来说,您可以通过以下方式避免重新定义变量名:
使用
__LINE__
预处理器符号(或__COUNTER__
,尽管 IIRC 不是标准的)。注意 creating a variable name with the preprocessor requires two levels of indirection (将链接中的VARIABLE
替换为__LINE__
)。A
do { /* code */ } while(0)
...据我所知,这是编写不仅仅是简单表达式的宏的最常见方式。立即执行的 lambda:
([](auto var) {/* 使用 var 的代码 */})(initExpressionForVar())
请注意,这些方法中的每一种实际上每次都会创建一个新变量,因此在语义上与您使用两个单独宏的方法不同!如果(分配的)变量的类型具有非默认赋值运算符,这一点尤其重要!
如果出于某种原因,您依赖于单个变量的重用和对其赋值,那么 IMO 最简单的方法是定义两个宏。一个宏声明变量(并在必要时初始化它),另一个宏包含使用该变量的代码。
关于c++ - 如何避免使用 C++ 宏重新声明变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55736643/