C++ Meta-programming
C++ Meta-programming
本文关键字:Meta-programming C++ 更新时间:2023-10-16
在C++
开发我的项目期间,我经常需要调试,我通常使用这个宏来做
#define DBUG(a) {std::cout << #a << " : " << a << std::endl;};
但是很多时候我需要做这样的事情
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
.
我不喜欢限制特定数量的参数。我没有找到一种静态解码名称的好方法,因此名称被组合为逗号分隔的字符串,然后在运行时解码。总的来说,这可能有点太重了,但至少,它按照要求做了,并且没有参数数量的限制(除了编译器限制,也就是说):
#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++ 引入的几个功能。
这是一个改编自这个答案的解决方案。您必须通过更改CHOOSER
宏和DBG
宏以及添加适当的DBG#
宏来定义宏以支持最多最大数量的参数。它也确实需要C++11。
#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
乙: 1
C: 5
您可以通过以下方式使用自己的DBUG(a)
DBUG(a << " " << b << " " << c);
使用一些好的 ol' C++11 可变参数模板怎么样?
#include <iostream>
#include <sstream>
#include <string>
template <typename T>
std::string make_string(const T& t)
{
std::ostringstream oss;
oss << t;
return oss.str();
}
template <typename Thead, typename ... Ttail>
std::string make_string(const Thead& head, const Ttail& ... tail)
{
return make_string(head) + make_string(tail...);
}
void debug(const std::string& msg)
{
std::cout << "DEBUG: " << msg << std::endl;
}
void debug(void)
{
std::cout << "DEBUG!" << std::endl;
}
template <typename ... Targs>
void debug(const Targs& ... args)
{
debug(make_string(args...));
}
int main(void)
{
int z;
debug("We're gonna crash: ", &z, "!");
debug();
debug(3.14);
}
相关文章:
- mbed os 5 c++ programming
- 在本书的示例代码中"introduction to 3d game programming with directx 11"
- "The C++ Programming Language"中所述的私有继承用法
- 为什么 Stroustrup 在 "The C++ Programming Language 3rd Edition (online)" 中定义了函数 sqrt?
- Winsock Programming - WsaGetSelectError,
- 什么样的C++模板编程可以称为"meta programming"?
- "MFC/C++ Socket programming.." 如何连接服务器和客户端?
- OpenGL and Windows Programming C++
- Qt Programming - QtConcurrence kill thread
- 无法从"C++ GUI Programming with Qt 4"生成查找对话框示例
- 在Boost Meta状态机的后端访问前端
- "The C++ Programming Language 4ed." [Stroustrup 2013] 具体类:"if the representation changes significan
- C++QT OSX QT::META+QT:键_Tab快捷键绑定
- Qt:Q_OBJECT中枚举的meta.enumeratorCount()没有元数据,原因是什么
- 我能否像在PythonQt中一样利用PyQt中的Qt Meta-Object系统?
- C++ Meta-programming
- 服务加载程序找不到服务提供程序类,即使类与 META-INF/services 位于同一 JAR 文件中也是如此
- Winsock Programming
- Qt programming QComboBox
- UNIX c programming