在尝试调查代码中的问题时,我是调试打印的粉丝:
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,bar和baz解决变量名,而不是字符串,是有可能使用他们的变量名创建的字符串"foo:","bar:"和"baz:"?你能编写一个带有未指定数量参数的函数或宏吗?
如果你有 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 解决方案直接解决此问题,但事实证明通过列表进行递归比您希望的更棘手。