如果你有 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 解决方案直接解决,但结果证明通过列表递归比您希望的要棘手。