首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++元编程

C++元编程
EN

Stack Overflow用户
提问于 2013-10-01 03:46:08
回答 4查看 581关注 0票数 3

在用C++开发我的项目时,我经常需要进行调试,我通常使用这个宏进行调试。

代码语言:javascript
复制
#define DBUG(a) {std::cout << #a << " : " << a << std::endl;};

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

代码语言:javascript
复制
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

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2013-10-01 04:48:36

我不喜欢对特定数量的争论加以限制。我没有找到一种很好的方法来静态地解码名称,所以这些名称作为逗号分隔的字符串放在一起,然后在运行时解码。总的来说,这可能有点太重了,但至少,它是按要求做的,并且没有限制参数的数量(除了编译器的限制,也就是说):

代码语言:javascript
复制
#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++修订版引入的几个特性。

票数 7
EN

Stack Overflow用户

发布于 2013-10-01 04:02:29

这里有一个来自this answer的解决方案。您必须通过更改CHOOSERDBG宏以及添加适当的DBG#宏来定义宏以支持最大数量的参数。它也需要C++11。

代码语言:javascript
复制
#include <iostream>

#define DBG1(a) std::cout << #a ": " << a << "\n"
#define DBG2(a, b) DBG1(a); DBG1(b)
#define DBG3(a, b, c) DBG2(a, b); DBG1(c)

#define CHOOSER(a, b, c, CHOICE, ...) CHOICE
#define DBG(...) CHOOSER(__VA_ARGS__, DBG3, DBG2, DBG1)(__VA_ARGS__)

int main() {
    int a{}, b{1}, c{5};
    DBG(a, b, c);
}

输出:

答:0 b: 1 c: 5

票数 4
EN

Stack Overflow用户

发布于 2013-10-02 15:46:30

您可以通过以下方式使用您自己的DBUG(a)

DBUG(a << " " << b << " " << c);

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19107597

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档