5

在尝试调查代码中的问题时,我喜欢调试打印:

cout << "foo:" << foo << "bar:" << bar << "baz:" << baz;

由于我经常编写这样的代码,如果我能使其通用且更易于键入,那就太棒了。也许是这样的:

DEBUG_MACRO(foo, bar, baz);

即使foo,barbaz解析为变量名,而不是字符串,是否可以使用它们的变量名来创建字符串"foo:","bar:""baz:"? 你能写一个函数或宏来接受未指定数量的参数吗?

4

3 回答 3

4

如果你有 C++11,你可以使用可变参数模板做一些类型安全且相当整洁的事情,例如:

#include <string>
#include <iostream>

template <typename T>
void debug(const T& v) {
  std::cout << v << "\n";
}

template <typename T, typename... Tail>
void debug(const T& v, const Tail& ...args) {
  std::cout << v << " ";
  debug(args...);
}

#define NVP(x) #x":", (x)

int main() {
  int foo=0;
  double bar=0.1;
  std::string f="str";
  debug(NVP(foo),NVP(bar),NVP(f));
}

此处的 NVP 宏完全是可选的,仅当您还想在代码中打印引用它的名称时才需要。

如果您真的想跳过 NVP 位,您可以使用 Boost 预处理器库(或滚动您自己的库),例如:

#include <string>
#include <iostream>
#include <boost/preprocessor/seq/for_each_i.hpp>
#include <boost/preprocessor/punctuation/comma_if.hpp>

template <typename T>
void debug_impl(const T& v) {
  std::cout << v << "\n";
}

template <typename T, typename... Tail>
void debug_impl(const T& v, const Tail& ...args) {
  std::cout << v << " ";
  debug_impl(args...);
}

#define NVP(x) #x":", (x)
#define MEMBER( r, data, i, elem ) BOOST_PP_COMMA_IF( i ) NVP(elem)

#define debug( members )                                \
  debug_impl(                                           \
  BOOST_PP_SEQ_FOR_EACH_I( MEMBER,, members )           \
  )


int main() {
  int foo=0;
  double bar=0.1;
  std::string f="str";
  debug((foo)(bar)(f));
}

以一些稍微奇怪的语法为代价。我的例子是基于这个答案。我尝试使用可变参数宏将其作为“纯”C++11 解决方案直接解决,但结果证明通过列表递归比您希望的要棘手。

于 2012-06-05T15:22:57.650 回答
1
#define DEBUG_MACRO(name) std::cout << #name << " = " << name << std::endl;

示例:http: //ideone.com/agw4i

于 2012-06-05T15:13:13.737 回答
0

你能写出一个接受未指定数量参数的函数吗?

是的,但通常你不应该这样做。

您可以通过在声明中使用省略号来声明一个接受未指定数量参数的函数:

int foo(string foo, ...)

但这有很大的问题。最大的问题是它破坏了类型安全。考虑当您错误地使用带有未指定参数列表的另一个函数时会发生什么:

int n = 42;
char buf[256] = {};
sprintf(buf, "%s", n);

这是一个错误——我指定了一个字符串,但传递了一个int. 最好的情况是这将在我第一次调试程序时执行并立即爆炸。然而,更有可能的是,代码永远不会运行,直到生产中第一次出现异常情况,然后它会在交易日中间让你的整个程序停机。客户会打电话对你大喊大叫,取消单位,等等……好吧,我有点夸张,但重点是类型安全是你的朋友,即使你和它有爱恨交织的关系。

于 2012-06-05T15:17:33.260 回答