C++元编程

use*_*292 3 c++ macros templates metaprogramming

在我的项目开发期间,我C++经常需要调试,我通常使用这个宏来完成它

#define DBUG(a) {std::cout << #a << " : " << a << std::endl;};
Run Code Online (Sandbox Code Playgroud)

但很多时候我需要做这样的事情

int a;
std :: string b;
double c;
...
...
DBG(a); DBG(b); DBG(c);
Run Code Online (Sandbox Code Playgroud)

但理想情况下,可能只是编写DBUG(a, b, c)DBG(a, b, c, d, e)更多变量来实现这样的事情.经过一些研究,这看起来像是元编程中的一个问题,或者更具体地说是代码生成,但由于我在这些领域的知识有限,我无法找到解决方法.

如果可能的话,我想在不使用Boost或其他外部库的情况下解决这个问题,并使用这些功能,C++98尽管如果不可能我愿意使用C++11.

Die*_*ühl 7

我不喜欢限制特定数量的参数.我没有找到一个静态解码名称的好方法,因此名称以逗号分隔的字符串组合在一起,然后在运行时解码.总的来说,这可能有点过于沉重,但至少,它确实如所要求的那样,并且对参数的数量没有限制(除了编译器限制之外):

#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();
}
Run Code Online (Sandbox Code Playgroud)

该代码使用了2011版C++引入的几个功能.