首页 > 其他分享 >C-中的编译期反射

C-中的编译期反射

时间:2023-07-01 19:55:05浏览次数:29  
标签:std __ name 反射 get 编译 size string

C++的编译期反射

我们可以利用__PRETTY_FUNCTION__这个宏获取当前函数的签名。
比如以下代码:

#include<fmt/core.h>
#include<string>

template<typename T>
std::string get_type_name(T n)
{
    return __PRETTY_FUNCTION__ ;
}

int main(int argc, char*  argv[])
{
      fmt::print(get_type_name<int>(3)+"\n");
}

输出:

std::string get_type_name(T) [with T = int; std::string = std::__cxx11::basic_string<char>]

如果是在Windows平台上,需要加上

#if !defined(__PRETTY_FUNCTION__) && !defined(__GNUC__)
#define __PRETTY_FUNCTION__ __FUNCSIG__
#endif

输出会是:

class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __cdecl get_type_name<int>(void)

为了方便叙述,后面还是主要以Linux平台为例。我们接下来就可以利用字符串切片得到编译器推导的类型,比如

template<typename T>
std::string get_type_name() {
    std::string function_sign{__PRETTY_FUNCTION__ };
    std::string_view find_str = "T = ";
    std::size_t size_str = find_str.size();
    std::size_t pos = function_sign.find(find_str);
    pos+=size_str;
    std::size_t pos2 = function_sign.find_first_of(";", pos);
    return function_sign.substr(pos, pos2-pos);
}

假如我们输出get_type_name<uint32_t>会得到unsigned int

同样我们可以输出数值模板推导的值:

template<typename T, T n>
std::string get_int_name(){
    std::string function_sign{__PRETTY_FUNCTION__ };
    std::string_view find_str = "n = ";
    std::size_t size_str = find_str.size();
    std::size_t pos = function_sign.find(find_str);
    pos+=size_str;
    std::size_t pos2 = function_sign.find_first_of(";", pos);
    return function_sign.substr(pos, pos2-pos);
}
fmt::print(get_int_name<char , 2>()+'\n');

我们会输出得到\002

假如我们想推导一个运行期的enum变量的值呢?

template<int begin_, int end_, typename F>
void static_for(F const& func){
    if constexpr (begin_ == end_) return;
    else{
        func(std::integral_constant<int, begin_>());
        static_for<begin_+1, end_>(func);
    }
}

template<typename T>
std::string get_int_name_dynamic(T n){
    std::string ret;
    static_for<0,6>([&](auto ic){
        constexpr auto i = ic.value;
        if(n == static_cast<T>(i)) ret = get_int_name<T, static_cast<T>(i)>();
    });
    return ret;
}

自然,我们可以直接反过来通过枚举名字符串返回一个枚举变量:

template<typename T, int begin_=0, int end_=256>
T enum_from_name(std::string const& enum_name){
   for(int i=begin_;i!=end_;i++)
   {
       if(enum_name == get_int_name_dynamic(static_cast<T>(i)))
           return static_cast<T>(i);
   }
   throw;
}

标签:std,__,name,反射,get,编译,size,string
From: https://www.cnblogs.com/wyfc4/p/17519815.html

相关文章

  • 关于编译器(转)
    原文:https://blog.csdn.net/wuhenyouyuyouyu/article/details/104669179/ 全部的语言编译器都拥有共通的中介架构:1.一个前端,用于解析匹配此语言的源代码,这个前端会产生一个抽象语法树;2.将此语法树翻译成为GCC的寄存器传递语言(registertransferlanguage)的后端。编译器......
  • petalinux SDK编译及使用
    petalinuxSDK编译及使用1、编译#petalinux-build--sdk2、打包#petalinux-package--sysroot注:SDK生成在<plnx-proj>/image/linux/sdk目录3、验证#sourceimages/linux/sdk/environment-setup-aarch64-xilinx-linux#echo$CCaarch64-xilinx-linux-gcc-march=armv8-a+crc......
  • windows上编译jdk
    目录Windows上编译jdk21环境准备编译Windows上编译jdk21参考文档:https://openjdk.org/groups/build/doc/building.html环境准备编译jdk需要unix环境,在windows上可以使用WSL或Cygwin.建议修改系统语言为英语(美国).笔者这里使用Cygwin,建议安装64位的Cygwin......
  • 八期day03-反编译工具和hook框架
    一反编译工具1.1常见反编译工具常见的反编译工具:jadx(推荐)、jeb、GDA反编译工具依赖于java环境,所以我们按照jdk1.2JDK环境安装#官方地址:(需要注册-最新java21)https://www.oracle.com/java/technologies/downloads/#下载地址链接:https://pan.baidu.com/s/1JxmjfGhW......
  • gcc/g++ 编译选项详解
    编译步骤gcc与g++区别gcc命令的常用选项编译优化选项-O优化-O1优化-O2-O0-Os-Ofast-Og-Oz-O选项控制特定的优化WarningsReference编译步骤gcc、g++分别是gnu的c&c++编译器。实际上,GCC能够编译三种语言:C、C++和Ob......
  • Swift 多Target预编译Preprocessor Macros中添加字段后不生效处理
    在其中一个Target的PreprocessorMacros中添加字段RVCTAG后,代码判断发现不生效代码逻辑如下#ifPROJECTIDreturntrue#elsereturnfalse#endif还需要在BuildSetting---> Swiftcompiler-CustomFlags--->OtherSwfitFlags中添加对应的宏设置,如下 ......
  • linux-tina-编译篇
    此篇对于网上搜寻的t113内核编译的整合篇:参考链接:芒果派百问网百问网是不能操作文件系统的,即是只读模式。芒果派也多多少少有很多的问题。下载与解压:这里以芒果派为例子,我是用百度盘下载的,git国内的网实在是更新不了。更新之后按照要求解压tarxvzfTinna..   然......
  • Linux编译过程以及生成中间文件--链接
    1、编译系统C源文件到可执行文件共经历了4个过程。在使用GCC编译程序时,编译过程可以被细分为四个阶段,包括预处理、编译、汇编、链接 1、预处理在预处理阶段,编译器主要作加载头文件、宏替换、条件编译的作用。一般处理带“#”的语句。 我们可以通过gcc的-E选项进行查看......
  • 内核文档翻译 —— Building External Modules(编译外部模块)
    原文:https://www.kernel.org/doc/html/latest/kbuild/modules.htmlThisdocumentdescribeshowtobuildanout-of-treekernelmodule.1.Introduction"kbuild"isthebuildsystemusedbytheLinuxkernel.Modulesmustusekbuildtostaycompatiblewi......
  • 编译python为可执行文件遇到的问题:使用python-oracledb连接oracle数据库时出现错误:DP
    错误原文:DPY-3010:connectionstothisdatabaseserverversionarenotsupportedbypython-oracledbinthinmode链接数据库方式如下:connection=create_engine("oracle+oracledb://user:password@host:post/dbname") PyCharm编译器内运行成功但编译后会有DP......