提问人:Guillaume BERLAND 提问时间:5/16/2023 更新时间:6/2/2023 访问量:86
无操作输出流
No-op output stream
问:
有没有办法创建一个基本上不做任何事情并且不评估代码的 ostream 实例?
例如:
#include <iostream>
#if defined(DEBUG)
#define LOG std::cout
#else
#define LOG std::ostream {nullptr}
#endif
#if defined(DEBUG)
std::string MyFunc()
{
return "mystring";
}
#endif
int main()
{
LOG << MyFunc() << std::endl;
return 0;
}
如果设置了标志“DEBUG”,则编译工作正常。否则,我有以下错误:
error: 'MyFunc' was not declared in this scope
是否可以在 null 流运算符之后跳过代码?
我找到了以下主题标准无操作输出流
答:
2赞
user253751
5/16/2023
#1
不,这是不可能的。
LOG << MyFunc() << std::endl;
类似于 。即使什么都不做,它仍然无法阻止被调用。operator<<(operator<<(LOG, MyFunc()), std::endl);
operator<<
MyFunc()
您可以改用宏技巧。如果你使用它是微不足道的,因为你可以用 .也可以(而不是这样,如果下一个喜欢是,它不会搞砸)。LOG(MyFunc() << std::endl);
LOG(anything)
#define LOG(...)
#define LOG while(0) std::cout
while
if
else
1赞
Pepijn Kramer
5/17/2023
#2
首先,不要在 C++ 中使用宏,除非你真的必须这样做。也没有必要编写一个什么都不做的流。使用 C++ 和格式库,您可以做到这一点。在发布模式下,这将编译为一个没有副作用的函数,可以完全优化。
话虽如此:尽量不要添加日志记录进行调试,使用单元测试(使用接口设计 + 依赖注入)并仅测试代码的某些部分是否独立工作(这将避免需要大量日志记录)。
#include <iostream>
#include <format>
#include <string_view>
// fmt is a standard std::format compatible format string
template<typename... args_t>
void Log(std::format_string<args_t...> fmt, args_t&&...args)
{
#ifdef _DEBUG
std::cout << std::format(fmt, std::forward<args_t>(args...));
#endif
}
int main()
{
Log("{},{}\n", "test", 42);
return 0;
}
评论
MyFunc