【问题标题】:How can I pass std::basic_streambuf<char>* into a function without #define如何在没有#define 的情况下将 std::basic_streambuf<char>* 传递给函数
【发布时间】:2021-09-04 12:06:29
【问题描述】:

我有一个简单的日志类,我想用它来记录哪个文件、行和函数创建了日志消息。我通过以下方式传递信息:

Logger::Log(LoggerLevel::ERROR, __FILE__ << ":" << __LINE__ << "::" << __FUNCTION__ << ":::" << logMessage);

这是我的 Logger 头文件。

#pragma once
#include <iostream>
#include <sstream>

enum class LoggerLevel { ERROR = -1, WARN = 0, INFO = 1, DEBUG = 2, TRACE = 3 };

class Logger
{
public:
  static LoggerLevel logLevel;
  static LoggerLevel GetLoggerLevel();
  static void LogMsg(LoggerLevel anLogLevel, const std::ostream &aMsg);
//  static void Log(LoggerLevel anLogLevel, const std::basic_streambuf<char> *aMsg)
//  {
//    LogMsg(anLogLevel, std::stringstream() << aMsg);
//  }
  
private:
};

#define Log(x, y) Logger::LogMsg(x, std::stringstream() << y)

我想知道如何在不使用底部的#define 的情况下做同样的事情,即使用类似于在我的头文件中注释掉的 C++ 函数。

当我尝试使用 C++ 函数时,我收到以下错误消息:

MyClass.cpp:65:44: error: invalid operands of types ‘const char [24]’ and ‘const char [2]’ to binary ‘operator<<’
   65 |   Logger::Log(LoggerLevel::ERROR, __FILE__ << ":" << __LINE__ << "::" << __FUNCTION__ << ":::" << logMsg);
      |                                   ~~~~~~~~ ^~ ~~~
      |                                   |           |
      |                                   |           const char [2]
      |                                   const char [24]

【问题讨论】:

  • 你不能使用这样的语法。如果您可以将语法更改为 Logger::Log(LoggerLevel::ERROR) &lt;&lt; __FILE__ &lt;&lt; ":" &lt;&lt; __LINE__; ,则可以使用。
  • @IgorTandetnik 我在搜索中看到了这个选项,但我希望可能有其他人在之前的问题中没有想到的另一种方式。您的回复在这里有类似的答案:stackoverflow.com/questions/6168107/…

标签: c++ logging stringstream ostream


【解决方案1】:

对于 C++14 及更高版本,我所追求的也可以通过一个函数来完成,该函数将 std::string 作为参数并用 + 替换 ostream 插入运算符来连接 std::strings。为了安全起见,我建议使用字符串文字进行连接:

    using namespace std::string_literals;
    Logger::Log(LoggerLevel::ERROR, __FILE__ + ":"s + std::to_string(__LINE__) + "::"s + __FUNCTION__ + ":::"s + logMsg);

Cortex0101 还提供了一个潜在的解决方案,我最初认为它在 C++20 中不起作用,但这只是因为我没有深入搜索标头。

#pragma once
#include <experimental/source_location> // std::experimental::fundamentals_v2::source_location
#include <string>                       // std::string

using src = std::experimental::fundamentals_v2::source_location;

enum class LoggerLevel { ERROR = -1, WARN = 0, INFO = 1, DEBUG = 2, TRACE = 3 };

class Logger
{
public:
  static LoggerLevel logLevel;
  static LoggerLevel GetLoggerLevel();
  static void LogMsg(LoggerLevel anLogLevel, const std::string &aMsg);
  static std::string GetCurrent(src cur)
  {
    using namespace std::string_literals;
    return (cur.file_name()+ ":"s + std::to_string(cur.line()) + "::"s + cur.function_name() + ":::"s);
  }
  
private:
};
Logger::LogMsg(LoggerLevel::INFO, Logger::GetCurrent(src::current()) + logMsg));

【讨论】:

    猜你喜欢
    • 2016-02-18
    • 2013-11-10
    • 2021-04-14
    • 2019-12-26
    • 1970-01-01
    • 2013-10-06
    • 2020-12-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多