文章目录

  • 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;
}

2.其他学习资料