如何在c ++中打印具有名称及其对应值的许多变量?

问题描述

#include <bits/stdc++.h>
using namespace std;

#define __deb(X...) (cout << "[" << #X << "]:" << X)
template <typename... type>
void debug(type &&... args)
{
    ((__deb(args)),...);
}

int main()
{
    int a = 1,b = 3;
    debug(a,b);
    return 0;
}

我得到的输出像[args]:1 [args]:3 但我想要类似[a]:1 [b]:3

输出

解决方法

一种方法是使用#__VA_ARGS__引用所有宏参数,然后在C ++函数中解析该字符串。

示例:

#include <iostream>
#include <sstream>
#include <string>
#include <utility>

template<typename T,typename... Args>
std::string debug_detail(const char* names,T&& var,Args&&... args) {
    std::stringstream builder;

    // find variable end
    const char* end = names;
    while(*end != ',' && *end != '\0') ++end;

    // display one variable
    (builder << ' ').write(names,end - names) << '=' << var;

    // continue parsing?
    if constexpr(sizeof...(Args) > 0) {
        // recursively call debug_detail() with the new beginning for names
        builder << debug_detail(end + 1,std::forward<Args>(args)...);
    }

    return builder.str();
}

template<typename... Args>
void debug_entry(const char* file,int line,const char* func,const char* names,Args&&... args) {
    std::stringstream retval;

    // common debug info
    retval << file << '(' << line << ") " << func << ':';

    // add variable info
    retval << debug_detail(names,std::forward<Args>(args)...) << '\n';

    std::cout << retval.str();
}

// the actual debug macro
#define debug(...) \
    debug_entry(__FILE__,__LINE__,__func__,#__VA_ARGS__,__VA_ARGS__)

int main() {
    int foo = 1;
    const int bar = 2;
    const std::string& Hello = "world";
    debug(foo,bar,Hello);
}

可能的输出:

./example.cpp(48) main: foo=1 bar=2 Hello=world

Demo

,

这是我的谦虚尝试,它使用宏FOO创建一对变量名及其值,并将参数传递给可变参数函数:

#include <utility>
#include <iostream>

#define FOO(var) std::make_pair(std::string(#var),var)

template <typename T>
void __deb(std::pair<std::string,T> arg) { std::cout << "[" << arg.first << "]:" << arg.second; }

template <typename... type>
void debug(std::pair<std::string,type> &&... args)
{
    (__deb(args),...);
}

int main()
{
    int a = 1,b = 3;
    debug(FOO(a),FOO(b));
}

Demo


或者,为避免对FOO中的每个变量进行宏调用debug,可以将debug定义为接受#__VA_ARGS__(参数字符串)的宏,然后__VA_ARGS__(参数值)。然后解析每个变量的名称和值:

#include <iostream>
#include <sstream>
#include <stdio.h>

#define debug(...) debug_print(#__VA_ARGS__,__VA_ARGS__)

template <typename T>
void __deb(std::istringstream &ss,T arg)
{
    //Extract name from stream
    std::string name;
    std::getline(ss,name,',');
    //trim leading space
    const auto pos(name.find_first_not_of(" "));
    name.erase(0,pos);
    std::cout << "[" << name << "]:" << arg;
}

template <typename... type>
void debug_print(const char* names,type&&...args)
{
    std::istringstream ss(names);
    (__deb(ss,args),...);
}


int main()
{
    int a = 1,b = 3,c = 4;
    debug(a,b,c);
}

Demo

,

问题在于,在不熟悉名称void debug(type &&... args)a的{​​{1}}上下文中使用了MACRO。

您的问题的可能解决方案是实现一个较大的MACRO,该MACRO可容纳多个var,并调用处理单个var(已实现)的sub-MACRO。

这样,初始MACRO调用将在具有所需var的调用函数的上下文中发生