一个更好的#define print std :: cout<

时间:2014-05-26 15:24:45

标签: c++ boost

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

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 ++ - ish方法 print("string)返回一个xPrint实例并且重载xPrint::operator%不起作用,因为我无法知道何时进行了最后一次%调用,是时候打印生成的格式字符串了。 / p>

注意:我需要boost :: format,所以printf / fflush不会这样做,我希望结果语法简洁。

1 个答案:

答案 0 :(得分:2)

我会建议像

这样的东西
#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);
}

编辑以下是一些黑客攻击此类打印声明的(有潜在危险!)的想法。下面的代码只是为了显示概念而不会按原样编译。使用风险自负!

a)通过为Forwarder添加专门化而不是使用析构函数来触发打印,将终止语句添加到operator%

将helper struct定义为终结符(最好是在命名空间中,但是你明白了......):

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)使用具有较少严格绑定和从右到左关联的运算符。你必须引入一个帮助器类型,虽然它可能是某种记录目标。

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

用法:

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

c)与上述相同,但使用了从左到右相关性的逗号运算符(yuck!)。

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

用法:

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