如何创建一个使用字符串格式的给定变量文本的宏(或其他工具)?

Cor*_*ein 5 c++ macros

在尝试调查代码中的问题时,我是调试打印的粉丝:

cout << "foo:" << foo << "bar:" << bar << "baz:" << baz;
Run Code Online (Sandbox Code Playgroud)

由于我经常编写这样的代码,如果我可以使它更通用并且更容易输入,那将是非常棒的.也许是这样的:

DEBUG_MACRO(foo, bar, baz);
Run Code Online (Sandbox Code Playgroud)

虽然foo,barbaz解决变量名,而不是字符串,是有可能使用他们的变量名创建的字符串"foo:","bar:""baz:"?你能编写一个带有未指定数量参数的函数或宏吗?

Fle*_*exo 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));
}
Run Code Online (Sandbox Code Playgroud)

这里的 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));
}
Run Code Online (Sandbox Code Playgroud)

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