C++ Macros #ifdef
C++ Macros #ifdef
void testFunc();
int myval = 0;
int main()
{
int a = 1;
if (a > 0)
{
#define TEST1
testFunc();
#undef TEST1
}
int b = 2;
if ( b > 0)
{
#define TEST2
testFunc();
#undef TEST2
}
std::cout << "val : " << myval << endl;
getchar();
return 0;
}
void testFunc()
{
#ifdef TEST1
#define HERE 1
#endif
#ifdef TEST2
#define HERE 2
#endif
#ifdef HERE
myval = HERE;
#else
myval = -1;
#endif
}
如何在第一次调用testFunc((时将HERE的值打印为1,然后在第二次调用时将HERE的值打印成2。
对于我所拥有的当前代码,正在打印的值是-1。
缺少的是预处理器指令在编译时之前进行求值。
这意味着当预处理器解析你的代码时:
- 设置TEST1
- 取消设置TEST1
- 设置TEST2
- 取消设置TEST2
- 检查是否定义了TEST1(未定义(
- 检查是否定义了TEST2(未定义(
- 检查是否定义了HERE(未定义(
这意味着testFunc
变成:
void testFunc() {
myval = -1;
}
然后,在这个预处理之后,您的代码就被编译了。
我会考虑使用预处理器之外的其他东西来实现您想要实现的目标。
按照您想要的方式,这是不可能的。宏是在编译之前进行评估的。它将简单地从上到下解析文档,并根据宏替换文本。当预处理达到testFunc
时,TEST1
和TEST2
都不再定义(您在代码的前面#undef
都定义了(,所以您最终得到了
void testFunc()
{
myval = -1;
}
然后对其进行编译。看起来你想创建一个类似于模板函数的东西?也许实际的函数模板可以解决您的问题。
如何在第一次调用testFunc((时将HERE的值打印为1,然后在第二次调用时将HERE的值打印成2。
这就是预处理后您尝试的函数的样子:
void testFunc()
{
myval = -1;
}
正如您所看到的,该函数不接受任何形式的输入,并且总是无条件地为全局变量分配相同的值。
使用宏无法实现您想要的功能。
要根据调用函数的次数打印不同的值,可以使用函数对象。功能对象可以具有内部状态:
auto testFunc = [HERE = 1]() mutable {
return HERE++;
};
std::cout << testFunc(); // prints 1
std::cout << testFunc(); // prints 2
所有#
语句都称为预处理器指令。这些是编译器的指令。您希望实际编译的代码能够维护程序运行时的某些状态。
有两种方法可以实现这一点,要么使用:
- 全局变量
- 静态变量
以下示例显示了这两种方法。每个函数也有一个内存值,它会被更新以记住该函数是否被调用过。
#include <iostream>
bool g_ran_already = false;
int first_different_global()
{
if (!g_ran_already)
{
g_ran_already = true;
return 1;
}
else
{
return 2;
}
}
int first_different_static()
{
static bool s_ran_already = false;
if(!s_ran_already)
{
s_ran_already = true;
return 1;
}
else
{
return 2;
}
}
int main(int argc, char** argv)
{
std::cout << "first_different_global() run 1: " << first_different_global() << "n";
std::cout << "first_different_global() run 2: " << first_different_global() << "n";
std::cout << "first_different_global() run 3: " << first_different_global() << "n";
std::cout << "first_different_static() run 1: " << first_different_static() << "n";
std::cout << "first_different_static() run 2: " << first_different_static() << "n";
std::cout << "first_different_static() run 3: " << first_different_static() << "n";
}
输出:
first_different_global() run 1: 1
first_different_global() run 2: 2
first_different_global() run 3: 2
first_different_static() run 1: 1
first_different_static() run 2: 2
first_different_static() run 3: 2
相关文章:
- #ifdef和未声明的标识符
- C++ Macros #ifdef
- 有没有办法在不使用 #ifdef 的情况下不编译发布版本中的单元测试函数体?
- C++ vcproj OutputDirectory macros
- 更新 #ifdef 中的现有变量值?
- 使用 constexpr 替换 #define 和 #ifdef 进行条件编译
- 使用 #ifdef 时的多个定义
- 使用 [#define & #ifdef] 跨文件激活代码块
- 以下 OpenCV 源代码中是否存在错误?(#ifdef 没有 #else)
- 有C++标准库 ifdef 或 ifndef 预处理器指令吗?
- C++预处理器同时执行#ifdef和#ifndef
- SFINAE-based ifdef
- 我们可以在INI文件中使用 #ifdef 宏,或者我们如何限制INI文件中写入的设置的编译?
- #ifdef 宏与 -Wpedantic 和 "extra" 分号
- 在静态库中使用 #ifdef(C++,Eclipse CDT)
- 如何避免使用IFDEF使代码更具测试
- C++ Overloading Macros
- IFDEF块内部对功能的未定义引用
- Constexpr vs macros
- 什么是通用运行时组件 #ifdef 适用于Windows(UWP)而不是iOS