c++ - C/C++ 可以在 marco 中使用“for loop”而不是“do while”吗?
问题描述
假设“cond”与程序中的任何名称不冲突,以下两个结构是否等效
#define DOWHILE do { (some_code); } while (0)
#define FORLOOP for(bool cond = true; cond; cond = false) (some_code)
这个问题的目的是:
我有这样的东西
bool printLogs; // nonconstant dynamic variable
而且我有一个宏(我不能做大的改变,这是一个大项目;我必须处理这个宏)#define LOG ...
,它的使用就像
LOG << "message" << 1 << 0.5 << 'a';
我希望这个宏变成
if (printLogs) {
PrinterClass() << "message" << 1 << 0.5 << 'a';
}
因此,如果未打印,则不会计算打印的参数。在这种情况下,我的解决方案是
#define LOG for(cond = printLogs; cond; cond = false) PrinterClass()
这个解决方案正确吗?还有其他方法吗?
更新:显然你不能if
在这里使用简单的。例如此代码将不起作用
#define LOG if(printLogs) PrinterClass()
int main() {
if (1)
LOG << 1;
else
LOG << 2;
}
更新 2:我希望看到我或您的解决方案正确性的解释。我必须确保该解决方案不会造成任何问题。您可以在代码中可以插入语句的任何位置插入“do while”构造。所以“do while”表现为一个简单的语句。我的建筑是这样吗?
更新 3:具有全局对象的解决方案不满足,因为它会导致巨大的开销
#include <atomic>
void printImpl(...);
std::atomic<bool> printLog;
struct Log {
template <typename T>
Log& operator<<(const T& t) {
if (printLog) {
printImpl(t);
}
return *this;
}
};
int main() {
Log() << 1 << 2;
}
毕竟优化会变成
int main() {
if (printLog) {
printImpl(1);
}
// Still should check because printImpl could have changed this variable.
// C++ does not provide any way to say "I promise it won't change printLog"
if (printLog) {
printImpl(2);
}
}
所以你对<<的每次使用都有原子比较。见https://godbolt.org/z/sEoUCw
解决方案
你可以这样做:
#define LOG if (!printLogs){} else PrinterClass()
推荐阅读
- c# - 如何更改从 monthCalendar 输出的日期格式
- ruby-on-rails - 如何扩展 ActiveSupport::TaggedLogging 以输出 json 行
- powershell - 如何检索正确的子网资源 ID 以创建虚拟网络规则?
- macos - Visual Studio Code (VSCode) 如何知道 ~/.config/fish/config.fish 中设置的环境变量?
- python-3.x - 如何从函数中获取值,并在另一个函数中使用它?
- c# - 如何在 c# 中创建一个对象数组,实例化一个带有一个参数的类?
- import - Filemaker Pro 18 从另一个文件导入记录
- ios - Codemagic IOS 构建需要很长时间才能完成
- assembly - (本地)标签如何在它自己的段(TASM 8086)之外结束?
- java - SQLServer 挂起使用“xplog70.dll”版本“xxx”执行扩展存储过程“xp_msver”