更好的#define打印std::cout<<boost::format

A better #define print std::cout<<boost::format

本文关键字:boost format cout #define 打印 std 更好      更新时间:2023-10-16

要快速插入简短的调试语句,我想转

print("%d %d %s") % i % j % str;

变成更详细的

std::cout << boost::format("%d %d %s") % i % j % str << std::endl;

上面提到的#define print std::cout<<boost::format没有endl,所以即使我在字符串中添加"n",如果在下一行发生崩溃,缓冲区也不会刷新。

更像c++的方法print("string)返回一个xPrint实例和重载xPrint::operator%不工作,因为我没有办法知道最后一次%调用已经完成,是时候打印结果格式字符串了。

注意:我需要boost::format,所以printf/fflush是不行的,我希望生成的语法简洁。

我的建议是

#define print(x) std::cout << (x) << std::endl

允许你执行

print(boost::format("%s") % str);

如果你真的坚持上面给出的简短版本,我能想到的最接近的是:

#include <iostream>
#include <boost/format.hpp>
class Forwarder
{
public:
  Forwarder(const std::string& s)
    : f(s)
  {}
  template <typename T>
  Forwarder& operator%(const T& t)
  {
    f % t;
    return *this;
    // You could even return a reference to f here instead if you wanted
  }
  ~Forwarder()
  {
    std::cout << f << std::endl;
  }
private:
  boost::format f;
};
#define print(x, y) { Forwarder f(x); f % y; }
int main()
{
  std::string str("Hallo");
  int i = 123, j = 456;
  print("%s %d %d", str % i % j);
}

EDIT这里有一些更多的(潜在的危险!)想法来破解这样的打印语句。下面的代码只是为了展示概念,不会按原样编译。使用风险自负!

a)Forwarder添加一个终止语句,为operator%添加一个专门化,而不是使用析构函数触发打印:

将helper结构定义为终止符(最好是在名称空间中,但您应该明白…):

struct END {};

专业模板:

template <>
Forwarder& Forwarder::operator%<END>(const END& t)
{
  std::cout << f << std::endl;
  return *this;
}

用法:

print("%s %d %d") % str % i % j % END;

b)使用约束不那么严格、从右到左结合的操作符。您必须引入一个helper类型,它可能是某种日志记录目标。

void operator<<=(Logger& l, const Forwarder& f) { ... }

用法:

DebugLogger <<= Forwarder("%s %d %d") % str % i % j;

c)与上面相同,但使用了逗号操作符(讨厌!),具有从左到右结合性。

void operator,(const Forwarder& f, Logger& l) { ... }

用法:

Forwarder("%s %d %d") % str % i % j, DebugLogger;