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 ソリューションとして直接解決するために、可変引数マクロを使用しようとしましたが、リストを再帰することは、期待するよりも難しいことがわかりました。