无操作输出流

No-op output stream

提问人:Guillaume BERLAND 提问时间:5/16/2023 更新时间:6/2/2023 访问量:86

问:

有没有办法创建一个基本上不做任何事情并且不评估代码的 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 流运算符之后跳过代码?

我找到了以下主题标准无操作输出流

C++ IOstream

评论

0赞 fabian 5/16/2023
不,C++ 函数调用需要计算所有参数...
0赞 Miles Budnek 5/16/2023
如果你愿意稍微改变你的语法,这样的东西可能会起作用。
0赞 463035818_is_not_an_ai 5/16/2023
有两件事需要考虑:a)你不一定需要0代码,只要编译器能够意识到代码什么都不做,任何代码都不如0代码。b) 有时打开或关闭调试日志记录不应过多地更改执行。在某些情况下,即使没有日志记录,您也希望被调用(无论是出于副作用还是仅仅为了调用它所需的时间)MyFunc
0赞 463035818_is_not_an_ai 5/17/2023
这个问题与 stackoverflow.com/questions/11826554/ 有何不同......
0赞 463035818_is_not_an_ai 5/17/2023
还是这个 stackoverflow.com/questions/11826554/......

答:

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::coutwhileifelse

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;
}