问题描述
#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
,
这是我的谦虚尝试,它使用宏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));
}
或者,为避免对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);
}
,
问题在于,在不熟悉名称void debug(type &&... args)
和a
的{{1}}上下文中使用了MACRO。
您的问题的可能解决方案是实现一个较大的MACRO,该MACRO可容纳多个var,并调用处理单个var(已实现)的sub-MACRO。
这样,初始MACRO调用将在具有所需var的调用函数的上下文中发生