如何将可变参数模板转换为多个单个模板?(C++竞争编程调试模板)
How to turn Variadic Templates into multiple single templates?(C++ Competitive Programming Debugging Template)
我的调试模板是:
#define ts to_string
string ts(char c) { return string(1, c); }
string ts(bool b) { return b ? "true" : "false"; }
string ts(const char* s) { return (string)s; }
string ts(string s) { return s; }
template<class A> string ts(complex<A> c) {
stringstream ss; ss << c; return ss.str(); }
string ts(vector<bool> v) {
string res = "{"; for(int i = 0; i < si(v); ++i) res += char('0' + v[i]);
res += "}"; return res; }
template<size_t SZ> string ts(bitset<SZ> b) {
string res = ""; for(int i = 0; i < SZ; ++i) res += char('0' + b[i]);
return res; }
template<class A, class B> string ts(pair<A,B> p);
template<class T> string ts(T v) { // containers with begin(), end()
bool fst = 1; string res = "{";
for(const auto& x: v) {
if (!fst) res += ", ";
fst = 0; res += ts(x);
}
res += "}"; return res;
}
template<class A, class B> string ts(pair<A,B> p) {
return "(" + ts(p.f) + ", " + ts(p.s) + ")"; }
void DBG() { cerr << "]" << endl; }
template<class H, class... T> void DBG(H h, T... t) {
cerr << ts(h); if (sizeof...(t)) cerr << ", ";
DBG(t...); }
#ifdef LOCAL // compile with -DLOCAL
#define dbg(...) cerr << "[" << #__VA_ARGS__ << "]: [", DBG(__VA_ARGS__)
#else
#define dbg(...) 0
#endif
当我打字时
dbg(a, n);
其中"a"是向量名称,n 是向量的大小。'a' 包含以下 {1, 2, 3, 4, 5} 和 n = 5
它打印
[a, n]: [{1, 2, 3, 4, 5}, 5]
但我希望它打印
[a]: [{1, 2, 3, 4, 5}]
[n]: [5]
无需键入
dbg(a);
dbg(n);
有什么办法可以做到这一点吗?
When I type
dbg(a, n);
I want it to print
dbg(a);
dbg(n);
Is there any way to do this?
在参数数上重载宏,并在每个参数的重载中调用回调。
// renamed from dbg
#define dbg_in(...) cerr << "[" << #__VA_ARGS__ << "]: [", DBG(__VA_ARGS__)
// overloads
#define dbg_1(_1)
dbg_in(_1)
#define dbg_2(_1,_2)
dbg_1(_1);dbg_in(_2)
#define dbg_3(_1,_2,_3)
dbg_2(_1,_2);dbg_in(_3)
// etc.
#define dbg_N(_1,_2,_3,_4,_5,_6,_7,_8,_9,N,...)
dbg_##N
#define dbg(...)
dbg_N(__VA_ARGS__,9,8,7,6,5,4,3,2,1)(__VA_ARGS__)
dbg(a, b);
// expands to: dbg_in(a);dbg_in(b);
Codeforce社区帮助了我,并告诉我正确的解决方案。
#define ts to_string
string ts(char c) { return string(1, c); }
string ts(bool b) { return b ? "true" : "false"; }
string ts(const char* s) { return (string)s; }
string ts(string s) { return s; }
template<class A> string ts(complex<A> c) {
stringstream ss; ss << c; return ss.str(); }
string ts(vector<bool> v) {
string res = "{"; for(int i = 0; i < si(v); ++i) res += char('0' + v[i]);
res += "}"; return res; }
template<size_t SZ> string ts(bitset<SZ> b) {
string res = ""; for(int i = 0; i < SZ; ++i) res += char('0' + b[i]);
return res; }
template<class A, class B> string ts(pair<A,B> p);
template<class T> string ts(T v) { // containers with begin(), end()
bool fst = 1; string res = "{";
for (const auto& x: v) {
if (!fst) res += ", ";
fst = 0; res += ts(x);
}
res += "}"; return res;
}
template<class A, class B> string ts(pair<A,B> p) {
return "(" + ts(p.f) + ", " + ts(p.s) + ")"; }
// DEBUG
void DBG(string names) { string s = names; }
template<class H, class... T> void DBG(string names, H h, T... t) {
auto pos = names.find(',');
auto first_name = names.substr(0, pos);
auto rest = names.substr(pos+1);
// Strip space at the beginning
while(rest.front() == ' '){
rest = rest.substr(1);
}
cerr << "[" << first_name << "]: [" << ts(h) << "]" << nl;
DBG(rest, t...);
}
#ifdef LOCAL
#define dbg(...) DBG(#__VA_ARGS__, __VA_ARGS__)
#else
#define dbg(...) 0
#endif
void EDBG() { cerr << "]" << endl; }
template<class H, class... T> void EDBG(H h, T... t) {
cerr << ts(h); if (sizeof...(t)) cerr << ", ";
EDBG(t...); }
#ifdef LOCAL // compile with -DLOCAL
#define edbg(...) cerr << "[" << #__VA_ARGS__ << "]: [", EDBG(__VA_ARGS__)
#else
#define edbg(...) 0
#endif
宏
edbg
不单独做,所以
edbg(a, n);
将输出
edbg(a, n);
而
dbg(a, n);
将输出
dbg(a);
dbg(n);
问题是#__VA_ARGS__
不会返回一个字符串列表,逗号分隔,变量的名称,变量的名称以逗号分隔。
所以你必须以某种方式拆分字符串。
如果你可以使用 C++17,我建议使用以下函数,该函数采用单个字符串,名称以逗号分隔,并返回一个具有单个名称的std::vector<std::string>
std::vector<std::string> splitWords (std::string const & s)
{
std::regex rgx ("\w+");
return { std::sregex_token_iterator{s.begin(), s.end(), rgx},
std::sregex_token_iterator{} };
}
以及可变参数模板dbgh()
(dbg 助手(函数,如下所示
template <typename ... Ts>
void dbgh (std::vector<std::string> v, Ts const & ... ts)
{
std::size_t i{};
((std::cerr << '[' << v[i++] << "]: [", DBG(ts)), ...);
}
所以你可以编写dbg()
可变参数宏,如下所示
#define dbg(...) dbgh(splitWords(#__VA_ARGS__), __VA_ARGS__)
相关文章:
- 如何将一个ostringstream十六进制字符串字符对转换为单个unit8t等价的二进制值
- 多个If语句与使用逻辑运算符计算条件的单个语句的比较
- 为什么模数运算符不适用于该代码
- 如何在C++中使用X509证书模在令牌中查找私钥
- 如何在QT中制作模态QProgressDialog?
- 模量行为 -1 % 3 (C++)
- Eclipse CDT:单个项目中有多个C++文件
- 为什么我们将单个或多维数组的大小声明为常量值?
- C++调用具有 *this 属性的单个帮助程序函数
- 如何读取单个字符并在输入两个字符序列时输出? 使用 while 循环和C++
- 如何将可变参数模板转换为多个单个模板?(C++竞争编程调试模板)
- 将多个 for 循环组合成单个迭代器
- 如何将多种语言设置放在单个 .clang 格式文件中
- 我可以通过取每个数字的模并取和来计算大数的模数吗?
- QT QOpenGLWidget:如何在不使用数据块复制的情况下修改VBO中的单个顶点值?
- 不同语言中的模运算符差异
- 在 c++ 中对单个排序数组中的 2 个未排序数组进行排序
- 与多个 for 循环与单个 for 循环 wrt 相关的性能从多映射获取数据
- C++:如何用单个命令替换复杂的迭代?
- C++单个生成文件多个二进制文件