在“测试模式"下打印信息但不在“正常执行"中
我在 c++ 中使用一个应用程序,它使用一个特殊的 dprintf 函数来打印信息,这是一个例子:
I am using an application in c++ that uses a special dprintf function to print information, this is an example:
dprintf(verbose, "The value is: %d", i);
这样做是当我为测试目的定义详细信息然后打印信息时,当我在正常执行中工作时,我没有定义它并且我没有在屏幕上看到无用的信息.我的问题是我如何才能实现该功能或实现相同的想法?.
What is doing is when I define verbose for test purposes then I print the information and when I am working in normal execution I do not define it and I do not see useless information in the screen. My question is how can I do that function or implement the same idea?.
推荐答案
我尽量避免使用 var-arg c 风格的函数,主要有两个原因:
I try to avoid using var-arg c-style functions for two main reasons:
- 它们不是类型安全的,不能使用运算符<<
- 他们不知道什么时候提供的参数太少或太多
我已经创建了一种使用 boost::fusion
的方法,它以类型安全的方式提供参数.它遍历这些参数,在遇到 %
时打印出来.如果给出的参数太少或太多,则抛出异常.
I've made a way that works using boost::fusion
, which is given arguments in a type-safe way. It iterates over those arguments, printing out them when a %
is encountered. If too few or too many arguments were given, an exception is thrown.
仍然存在一个问题:可变参数宏在 C++ 中还不是标准.所以,我做了两个版本.一种适用于当前 C++ 的方法.您必须使用
There is one problem still: Variadic macros are not yet standard in C++. So, i have made two versions. One that work with current C++. You have to invoke it using
dprintf("name: %, value: %
", ("foo", 42));
那么.使用可变参数宏的另一个版本可以通过定义预处理器符号来使用,它使您能够编写
Then. The other version, using variadic macros, can be used by defining a preprocessor symbol, which enables you to write
dprintf("name: %, value: %
", "foo", 42);
这是代码.boost.fusion
为此提供了更多详细信息:
Here is the code. The boost.fusion
provides more details for this:
#include <boost/fusion/include/sequence.hpp>
#include <boost/fusion/include/make_vector.hpp>
#include <boost/fusion/include/next.hpp>
#include <stdexcept>
#include <iostream>
template<typename IterS, typename IterSeqE>
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<typename IterS, typename IterSeqB, typename IterSeqE>
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<typename Seq>
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
", ("litb", 22));
}
相关文章