在 C++
中开发我的项目期间,我经常需要调试,我通常使用这个宏来完成它
#define DBUG(a) {std::cout << #a << " : " << a << std::endl;};
但很多时候我需要做这样的事情
int a;
std :: string b;
double c;
...
...
DBG(a); DBG(b); DBG(c);
但理想情况下,可能只为更多变量编写
DBUG(a, b, c)
或 DBG(a, b, c, d, e)
来实现这样的目标。经过一些研究,这看起来像是元编程或更具体的代码生成中的一个问题,但由于我在这些领域的知识有限,我找不到解决它的方法。如果可能的话,我想在不使用 Boost 或其他外部库的情况下解决这个问题,并使用
C++98
中的功能,尽管如果不可能,我愿意使用 C++11
。 最佳答案
我不喜欢限制特定数量的参数。我没有找到一种很好的方法来静态解码名称,因此将名称作为逗号分隔的字符串放在一起,然后在运行时解码。总的来说,这可能有点太重了,但至少,它按照要求执行并且没有对参数数量的限制(编译器限制除外):
#include <iostream>
#include <sstream>
#include <iterator>
#include <algorithm>
#include <tuple>
#include <vector>
#include <type_traits>
#include <stdlib.h>
template <int I, int S, typename... V>
typename std::enable_if<I == S>::type
debug_var(std::vector<std::string> const&, std::tuple<V...> const&)
{
}
template <int I, int S, typename... V>
typename std::enable_if<I != S>::type
debug_var(std::vector<std::string> const& n, std::tuple<V...> const& v)
{
std::cout << n[I] << '=' << std::get<I>(v) << ' ';
debug_var<I + 1, S>(n, v);
}
template <typename... V>
void debug(std::vector<std::string> const& n, std::tuple<V...> const& v)
{
debug_var<0, sizeof...(V)>(n, v);
std::cout << '\n' << std::flush;
}
std::vector<std::string> debug_names(char const* names)
{
std::vector<std::string> result;
std::istringstream in(names);
for (std::string name; std::getline(in >> std::ws, name, ','); ) {
result.push_back(name);
}
return result;
}
#define DEBUG(...) debug(debug_names(#__VA_ARGS__), std::tie(__VA_ARGS__));
int main()
{
int a=1, b=2;
DEBUG(a, b);
DEBUG();
}
该代码使用了 2011 年 C++ 修订版引入的几个功能。
关于C++ 元编程,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19107597/