文章目录
- 1.样例代码
- 2.其他学习资料
1.样例代码
#include <iostream>
#include <string>
#include <stdexcept>
using namespace std;
#define LOG(x) (cout << __FILE__ << ":" << __LINE__ << ": " << __FUNCTION__ << ": " << __PRETTY_FUNCTION__ << ": " << (x) << endl)
template <class T>
void func(T a)
{
LOG("func(T a)");
}
void func()
{
LOG("func()");
}
// 获取T是什么,获取类型的实际名字
template <typename T>
string get_type_name()
{
string s = __PRETTY_FUNCTION__;
auto pos = s.find("T = ");
pos += 4;
auto pos2 = s.find_first_of(";]", pos);
return s.substr(pos, pos2 - pos);
}
template <typename T, T N>
string get_int_name()
{
string s = __PRETTY_FUNCTION__;
std::cout << s << std::endl;
auto pos = s.find("N = ");
pos += 4;
auto pos2 = s.find_first_of(";]", pos);
return s.substr(pos, pos2 - pos);
}
enum Color
{
RED = 1,
GREEN = 2,
BLUE = 3,
};
namespace My
{
enum Color
{
RED = 1,
GREEN = 2,
BLUE = 3,
};
}
// 反射:运行时确定变量的类型,上面都是编译期确定的
template <typename T>
string get_int_name_dynamic(T n)
{
if (n == (T)1)
return get_int_name<T, (T)1>();
if (n == (T)2)
return get_int_name<T, (T)2>();
if (n == (T)3)
return get_int_name<T, (T)3>();
}
template <int N>
struct int_constant
{
static constexpr int value = N;
};
template <int Beg, int END, class F>
void static_for(F const &func)
{
if constexpr (Beg == END)
{
return;
}
else
{
func(int_constant<Beg>());
static_for<Beg + 1, END>(func);
}
}
template <typename T>
string get_int_name_dynamic_new(T n)
{
string ret;
// C++17以内,lambda只有()参数,C++20支持模板参数
// [&]<typename T>(T i){}
static_for<0, 256>([&](auto i)
{
if (n == (T)i.value)
ret = get_int_name<T, (T)i.value>(); });
return ret;
}
template <bool Cond>
struct my_enable_if
{
};
template <>
struct my_enable_if<true>
{
typedef int type;
};
template <class T, T N>
const char *get_enum_name_static()
{
return __PRETTY_FUNCTION__;
}
template <int Beg, int End, class F, typename my_enable_if<Beg == End>::type = 0>
void static_for_n(
F const &func) {}
template <int Beg, int End, class F, typename my_enable_if<Beg != End>::type = 0>
void static_for_n(
F const &func)
{
struct int_constant
{
enum
{
value = Beg
};
};
func(int_constant());
static_for_n<Beg + 1, End>(func);
}
template <int Beg = 0, int End = 256, typename T>
string get_enum_name_new(T n)
{
string s;
static_for_n<Beg, End + 1>([&](auto i)
{ if (n == (T)i.value) s=get_enum_name_static<T, (T)i.value>(); });
if (s.empty())
return std::to_string((int)n);
auto pos = s.find("N = ");
pos += 4;
auto pos2 = s.find_first_of(";]", pos);
s = s.substr(pos, pos2 - pos);
size_t pos3 = s.find("::");
if (pos3 != s.npos)
s = s.substr(pos3 + 2);
return s;
}
template <typename T, int Beg = 0, int End = 256>
T enum_from_name(string const &s)
{
for (int i = Beg; i < End; ++i)
{
if (s == get_enum_name_new((T)i))
return (T)i;
}
// throw;
// std::out_of_range();what不直观
std::cout << "AAA" << std::endl;
throw std::runtime_error("hello");
// throw;
}
int main()
{
// func();
// func(3);
// func(3.14f);
cout << get_type_name<string>() << endl;
cout << get_int_name<int, 1>() << endl;
cout << get_int_name<Color, (Color)1>() << endl;
constexpr Color c = RED;
cout << get_int_name<Color, c>() << endl;
Color c1 = RED;
cout << get_int_name_dynamic(c1) << endl;
// 给一个枚举变量的值,返回一个其对应的字符串
cout << get_int_name_dynamic_new(RED) << endl;
My::Color c2 = My::RED;
cout << get_enum_name_new(c2) << endl;
cout << enum_from_name<Color>("7877") << endl;
}
- 参考:scienum.h
2.其他学习资料
- parallel101/course
- C++并发编程(中文版)(C++ Concurrency In Action),C++ Concurrency In Action原始的github链接、代码、以及优秀笔记
- 参考:鲜为人知的C++黑科技【PRETTY_FUNCTION】非侵入式的编译期反射