我在c ++中使用一个使用特殊dprintf函数打印信息的应用程序,这是一个例子:
dprintf(verbose, "The value is: %d", i);
我正在做的是当我为测试目的定义详细信息然后我打印信息时,当我正常执行时,我没有定义它,我没有在屏幕上看到无用的信息.我的问题是我该如何实现这一功能或实现相同的想法?
我试图避免使用var-arg c风格函数有两个主要原因:
它们不是类型安全的,不能使用operator <<
当提供的论点太少或很多时,他们无法识别
我已经找到了一种可以使用的方法boost::fusion
,它以类型安全的方式给出了参数.它迭代这些参数,在%
遇到时打印出来.如果给出的参数太少或太多,则抛出异常.
还有一个问题:Variadic宏在C++中还不是标准的.所以,我已经制作了两个版本.适用于当前C++的一个.你必须使用它来调用它
dprintf("name: %, value: %\n", ("foo", 42));
然后.使用可变参数宏的另一个版本可以通过定义预处理器符号来使用,这使您可以编写
dprintf("name: %, value: %\n", "foo", 42);
这是代码.在boost.fusion
提供了更多细节:
#include#include #include #include #include template void print_vec(IterS b, IterS e, IterSeqE, IterSeqE) { while(b != e) { if(*b == '%') { if(++b != e && *b == '%') { std::cout << '%'; } else { throw std::invalid_argument("too many '%'"); } } else { std::cout << *b; } ++b; } } template void print_vec(IterS b, IterS e, IterSeqB seqb, IterSeqE seqe) { while(b != e) { if(*b == '%') { if(++b != e && *b == '%') { std::cout << '%'; } else { std::cout << *seqb; return print_vec(b, e, next(seqb), seqe); } } else { std::cout << *b; } ++b; } throw std::invalid_argument("too few '%'"); } template void print_vec(std::string const& msg, Seq const& seq) { print_vec(msg.begin(), msg.end(), begin(seq), end(seq)); } #ifdef USE_VARIADIC_MACRO # ifdef DEBUG # define dprintf(format, ...) \ print_vec(format, boost::fusion::make_vector(__VA_ARGS__)) # else # define dprintf(format, ...) # endif #else # ifdef DEBUG # define dprintf(format, args) \ print_vec(format, boost::fusion::make_vector args) # else # define dprintf(format, args) # endif #endif // test, using the compatible version. int main() { dprintf("hello %, i'm % years old\n", ("litb", 22)); }
#ifdef DEBUG #define dprintf(format, ...) real_dprintf(format, __VA_ARGS__) #else #define dprintf #endif
这里real_dprintf()是被调用的"真实"函数,而dprintf()只是一个包装调用的宏.