【问题标题】:streamed variables as a function parameter in C++流式变量作为​​ C++ 中的函数参数
【发布时间】:2015-09-16 13:23:18
【问题描述】:

当您将变量流式传输到 cout 等输出流时,类型转换是自动的。我想弄清楚的是如何通过函数调用来做到这一点,例如:

inline void DEBUG(ostream& s)   // Don't know if this prototype is appropriate
{
  cout << s;
}


main()
{
  int i = 5;

  DEBUG("The value is: " << i << endl); // This doesn't compile

  DEBUG("The value is: " + i + endl); // Neither does this
}

我在这里发现了类似的问题,但它们都涉及将流对象作为参数传递,而我试图将 “流数据” 传递给已经具有流对象的函数,所以反过来。这甚至可能吗?我不想诉诸显式类型转换。我也找到了this question,但如果可以避免的话,我真的不想写一个完整的记录器类。

目前我将它作为一个宏来实现,它可以工作,但如果可能的话,我宁愿使用内联函数。

#define DEBUG(s)    (cout << s)

【问题讨论】:

  • 那个“整个记录器类”不到二十行代码。

标签: c++ stream type-conversion


【解决方案1】:

当然它不会编译。原因有很多。

首先,运算符

第二,操作符

"The value is: " << i
顺便说一下,

+ 也没有为文字定义。

要实现您想要看到的语义,您必须从流开始。字符串文字需要首先转换为流,然后您可以对其应用

编辑:

既然我明白了其中的原理,我可以给出一个更好的答案。人们试图以多种方式统一地隔离不同级别的调试,并且有几个针对此的库(log4cpp、boost.log 仅举几例)。在您开始实现自己的日志记录之前,我肯定会建议您研究一下。良好的日志记录不仅仅是调试级别。

如果出于任何原因,您想使用自己的自制软件,您可以探索以下几种方法:

  • 使用您自己的记录器类(非常罕见的示例之一,接近 单身!适合单例的地方)。您可以设置 应用程序开始时的日志记录级别,而不仅仅是 调用 Logger::debug()
  • 使用宏丰富上述解决方案。函数的问题在于,与宏不同,它们松散了上下文。所以如果你想记录日志调用的文件和行号(你通常会这样做!),你可能想做 LOG_DEBUG
  • 完成此操作后,您会发现有时会调用
  • 传奇还在继续……准备好使用库了吗?

【讨论】:

  • 额外间接的唯一原因是在代码中有一个地方可以启用/禁用“DEBUG”级别输出,同时仍然具有其他级别的输出,例如“INFO”和“WARN” ”。有没有更好的方法来做到这一点?也许我可以 typedef 一个名称指向 cout,然后将 typedef 更改为指向某个空流?
  • 没有。你不能 typedef std::cout。但现在我知道你在做什么,所以我会更新答案。
  • 谢谢你,这是很多毫无疑问会帮助某人的信息。但是由于您建议使用库或记录器类+大量宏,而我只使用一个宏,所以我想我现在会坚持使用我的 1 宏。也许在一个更大的项目中我会做不同的事情。再次感谢。
【解决方案2】:

嗯,(至少有一些)日志库会做的是创建一个临时代理对象来充当流:

#include <iostream>

struct LoggerProxy {
    LoggerProxy(const char* file, int line)
    {
        std::cout << "File " << file << ", line " << line << ": ";
    }

    template<typename T>
    LoggerProxy& operator<<(T&& t)
    {
        std::cout << t;
        return *this;
    }
};

#define LOG_DEBUG LoggerProxy{__FILE__, __LINE__}

int main()
{
    LOG_DEBUG << "Value is: " << 4;
}

您可以用它做很多花哨的事情,例如调试级别检查、输出到不同的流或多个后端(例如同时输出到 std::cout/cerr 和日志文件)等等。

【讨论】:

    猜你喜欢
    • 2020-10-28
    • 1970-01-01
    • 2017-10-20
    • 2020-09-13
    • 2011-03-19
    • 2013-12-23
    • 2014-12-28
    • 2014-10-24
    • 2021-08-21
    相关资源
    最近更新 更多