当前位置: 首页 > news >正文

详解 c++17 重载类 overload的每一条语句,附实例.


author: hjjdebug
date: 2025年 05月 09日 星期五 16:21:03 CST
description: 详解 c++17 重载类 overload的每一条语句


文章目录

  • 1. template 模板类.
  • 2. class... Ts 是什么意思?
  • 3. template<class... Ts> 是什么意思?
  • 4. overload 是什么?
  • 5. Ts... 是什么?
  • 6. 小结
  • 7. using Ts::operator()... 是什么意思?
  • 8. overload(Ts...)-> overload<Ts...>
  • 9 附上我的研究代码.
  • 10. 这个重载类有什么用呢?

我看到了几行奇怪的代码,我想理解它的意思.

template<class... Ts>
struct overload : Ts... {
using Ts::operator()...;
};template<class... Ts>
overload(Ts...)-> AAA<Ts...>;

1. template 模板类.

template 是一个c++关键字,代表模板类.
模板类在编译时是不生成代码的, 当实例化时,给了具体的类型,才生成对应的代码.

2. class… Ts 是什么意思?

如果没有… 而是 class Ts, 它的含义是类型名称 是Ts, 这也是基本使用方法.
其中Ts 是描述符.
而这里 class… Ts, 则表示Ts 代表了很多类型.
Ts 是一个描述符,也可以替换它为你喜欢的名称,它本来是Types简写,用Ts代替已经很简洁了.

3. template<class… Ts> 是什么意思?

是定义一个模板类,它的参数类型有很多种, Ts是型参的名称

4. overload 是什么?

overload 是一个类型的名称, 它是一个普通的描述符
我把overload改成AAA, 编译是照样可以通过的,只不过模板类型的名称就叫AAA了.

5. Ts… 是什么?

Ts… 代表的是多种类型的意思,Ts是型参的名称
这些都是跟编译器的约定,被改编之后的gcc,是理解你的这种用法的.

6. 小结

template<class… Ts>
struct AAA : Ts… {
};
定义了一个模板类型,其名称叫AAA, 该模板输入参数类型很多.
该AAA类型公有继承了它的子类型 各个Types, 因而它可以使用各个子Types 中定义的函数.
struct 的继承默认是公有继承 public 类型, 当然你也可以显示声明为public.

7. using Ts::operator()… 是什么意思?

此处的 using 语句,表明它要使用各基类Ts的() 操作符,使基类的函数操作符为可见.
这样就可以用小括号包住子对象.
如果你注释掉该语句,则s(1),s(“1”),s(st)等编译时都会出现错误,编译器不知道你用小括号包住子变量是什么意思.
其实我们括注子变量当然是构造对象时传递的一个参数的意思,
不知道模板类为什么不把它做为一种默认的行为?
而必需要我们显示的像上面那样来说明.

8. overload(Ts…)-> overload<Ts…>

-> 代表推导的意思.
它告诉gcc, 当你碰到overload(Ts…)的使用方法时,就去实例化一个overload<Ts…>类型
这里我也有点不清楚,这难道不应该是默认的行为吗? 为什么还要我们显示说明呢?
也就是说按我的意思,只要用了…多类型,就不用声明using,及模板类型推导语句,岂不是更简洁!

9 附上我的研究代码.

 cat main.cpp
#include <iostream>
#include <string>
using namespace std;
//class... Ts,说明Ts可代表多种类型
template<class... Ts>
//AAA 类继承了Ts类, Ts...表示多种类型
struct AAA : Ts... {// using 关键字,引入基类Ts::operator(),使其到父类作用域中//此处using 的作用是防止基类函数被隐藏//基类函数被隐藏是说当基类中有一个函数,派生类中有同名函数,则基类函数被隐藏.//有多个operator(), 将来会调用那一个? 这是编译器的函数重载功能.using Ts::operator()...; // 注释掉该语句, s(1)调用会出现error: request for member ‘operator()’ is ambiguous
};//class 说明是一种类型,...是多种类型,Ts是一个标识符,代表类型types
template<class... Ts>
//Ts... Ts,任意类型...任意个数
//推导规则,当调用AAA(Ts...),推导出类型AAA<Ts...>
//注释掉该语句,当声明AAA变量s 时,
//会有错误 cannot deduce template arguments of ‘AAA<Ts>’, as it has no viable deduction guides
AAA(Ts...)-> AAA<Ts...>; 
//这是给编译器沟通的语言,通过构造函数的参数类型,推导出模板的类型
//所以这种写法几乎构成了固定的搭配typedef struct _Test
{int a;int b;//这里的operator() 给模板类中的using Ts::operator 没有任何关联void operator()(struct _Test st){cout<<"struct _Test"<<st.a<<endl;}
}Test;
int main() {//定义一个AAA类型的变量s,其有有2种构造函数,当参数类型为int时,为一种,当参数类型为string时,为另一种//AAA 实际的功能是一个重载类型AAA s{ //多个lamda 表达式[](int){ cout << "int" << endl; }, [](string){ cout << "string" << endl;},[](Test){ cout << "Test struct"<<endl;}};Test st;s(1); // int 参数,与AAA:: using Ts::operator() 有关联,变量函数式.s("1"); // string参数,与AAA:: using Ts::operator() 有关联s(st); //自定义的struct _Test 类型, 也与AAA:: using Ts:operator()有关联cout<<"sizeof(AAA):"<<sizeof(s)<<endl; //AAA类型大小是一个象征性大小1,它是不占用内存的.
}

代码的执行结果:
$ ./overload
int
string
Test struct
sizeof(AAA):1

10. 这个重载类有什么用呢?

这个重载类,它不是装东西的,因为它实例的大小只是象征性大小1.
但它能够根据不同的参数类型,调用不同的构造函数.
这是跟编译器的约定.
跟编译器约好了模板,约好了…,约好了由参数类型导出模板类型(需显式说明),约好了函数式子类型(需显式说明)
就这么点意思,搞的好复杂.有这个必要吗?语言的复杂性正在掩盖一些本质的东西.
使用起来似乎能简洁一点,但理解起来复杂了一点.

相关文章:

  • LintCode1343-两字符串和,1535-转换成小写字母
  • 强化学习三大基本方法-DP、MC、TD
  • setData执行后操作方法-微信小程序
  • AD 绘制原理图--元件的放置
  • 服务器多客户端连接核心要点(1)
  • 11.多用组合和少继承
  • 关税新政冲击波:海外仓成跨境电商角逐美国市场“利刃”?
  • OpenHarmony SystemUI开发——实现全局导航栏和状态栏关闭
  • powershell_bypass.cna 插件(适配 Cobalt Strike 4.0 的免费版本下载地址)
  • selenium替代----playwright
  • 分析NVIDIA的股价和业绩暴涨的原因
  • 计算机二级WPS Office第三套电子表格
  • 苍穹外卖--公共字段自动填充
  • Windows 忘记密码怎么办?
  • 深度解析动态IP业务核心场景:从技术演进到行业实践
  • 使用Python删除PDF中多余或空白的页面
  • 升级element-ui步骤
  • nacos-server-2.2.2.tar及使用方式
  • 【UEFN】用于可靠多模态情感分析的高效不确定性估计融合网络
  • 【Java基础】——集合篇
  • 明查|哈佛大学批改美教育部长来信,红笔标出语法错误?
  • 晋级中部非省会第一城,宜昌凭什么
  • 河南省省长王凯在郑州调研促消费工作,走访蜜雪冰城总部
  • 比尔·盖茨:未来20年通过盖茨基金会捐出几乎全部财富,2045年底基金会停止运营
  • 昆明阳宗海风景名胜区19口井违规抽取地热水,整改后用自来水代替温泉
  • 中消协点名新能源汽车行业:定金退款争议频发