IE盒子

帖子
查看: 93|回复: 0

C++ 学习:查看模板实例的工具

[复制链接]

3

主题

10

帖子

16

积分

新手上路

Rank: 1

积分
16
发表于 2023-2-7 14:31:38 | 显示全部楼层 |阅读模式
模板在使用之前会生成实例,我们可以通过一些工具查看模板实例后的代码,帮助我们学习模板,本文将介绍2种查看模板实例的的方法。
第一种 cppinsights

cppinsights
这个网站可以生成你的模板实例。比较方便。
第二种 clang命令

clang++ -Xclang -ast-print -fsyntax-only xxx.cpp
所以这个命令需要clang。
通过这个命令会在控制台生成模板实例。不过会特别的杂乱,如果你包含了其他头文件,可能会生成很多附加的模板展开。因此需要对这些生成的代码简单修整一下。
我通过python写了一个脚本,直接读取cpp,在指定区域生成模板实例,且可以存入txt备用。源码在下面,可直接使用。使用也不复杂。(Windows下使用)
#--main.py--
# -- coding: utf-8 --
import os
import re
import sys

cmd = "clang++ -Xclang -ast-print -fsyntax-only"
# 执行cmd并返回值
def start_cmd(filename: str, std: str = 'c++17'):
    xcmd = f"{cmd} -std={std} {filename}"
    result = os.popen(xcmd)
    want = result.read();
    result.close()
    return want
# 处理结果
def sub_string(txt_: str):
    rs_ls1 = re.findall("(?<=(bbegin[(][)];))([\s\S]*)(?=(void eend[(][)]))", txt_)  # 括号要用z中括号抱起来
    if len(rs_ls1)==0:
        print(txt_)
        return txt_
    print(rs_ls1[0][1])
    return rs_ls1[0][1]
# 写入文本
def write_txt(data: str, name: str = "xxx"):
    with open(f"{name}.txt", "w") as f:
        f.write(data)
# 读取命令行
def get_args():
    args = sys.argv[:]
    if len(args)<2 or len(args)>3:
        exit(1)
    return args
# 切割字符串
def spt_str(filename:str):
    if '\\' in filename:
        filename = filename.split('\\')[-1]
    filename = filename.split('.')[-2]
    return filename

flag = False #如果是True 则会将生成的代码存入txt中
if __name__ == "__main__":
    args = get_args()
    filename = spt_str(args[1])
    get = start_cmd(args[1]) # 获得cmd运行后输出的结果
    get1 = sub_string(get) # 将结果修整一下
    if flag:
        write_txt(get1,filename) #写入文本大致思路是执行clang的那个命令,将它生成的生成的代码简单处理一下。
使用说明

在命令行中运行下面命令
python main.py [cpp的路径] <C++的标准>
示例:python main.py .\test.cpp c++17

  • 第一个参数(必填) 绝对路径和相对路径都可以(可以直接把cpp文件拖到控制台中),
  • 第二个参数(可选) 默认是c++17。可更改为c++14等.
注意点


  • 在于要生成模板示例的部分,用void bbegin(); XXXX  void eend();用这2个函数声明包起来 只会产生XXXX这部分的模板实例代码。
  • python代码中有一个全局变量flag,是用来控制是否输出到一个txt文本中,默认设置为false,如果需要,可以把它设置成true。
使用示例

test.cpp
#include <iostream>

void bbegin(); //起始点
template <class... T> void print_(const T &...arg) {
  (std::cout << ... << arg) << std::endl;
}
template <bool f, class U, class... T>
constexpr auto sub_1(const U &val, const T &...arg) {
  if constexpr (f)
    return (val - ... - arg);
  else
    return (arg - ... - val);
}
void func() {
  print_("hhh", 'k', 1);
  auto x1 = sub_1<false>(10, 3, 5);
}
void eend();//结束点
执行命令  
python .\main.py .\test.cpp
test__.cpp 模板实例代码
template <class ...T> void print_(const T &...arg)
{
    (std::cout << ... << arg) << std::endl;
}
template<> void print_<<char[4], char, int>>(const
char &arg[4], const char &arg, const int &arg) {
    std::cout << arg << arg << arg << std::endl;
}
template <bool f, class U, class ...T> constexpr auto sub_1(const U &val, const T &...arg) {
    if (f)
        return (val - ... - arg);
    else
        return (arg - ... - val);
}
template<> constexpr int sub_1<false, int, <int, int>>(const int &val, const int &arg, const int &arg) {
    if (false)
        ;
    else
        return arg - arg - val;
}
void func() {
    print_("hhh", 'k', 1);
    auto x1 = sub_1<false>(10, 3, 5);
}
闲言

刚开始是用C++直接写这个小工具,但是Windows下读取cmd的内容不大方便,需要权限。。。
回复

举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表