c++17 推断指南(deduction guide)

news/2024/10/6 6:51:00
 
 
namespace _nmsp2
{template<typename T>struct A{A(T val1, T val2){cout << "A::A(T val1,T val2)执行了!" << endl;}A(T val){cout << "A::A(T val)执行了!" << endl;}};template<typename T>A(T)->A<T>;
}
namespace _nmsp3
{template<typename T>struct B{T m_b;T m_b2;};template<typename T>B(T)->B<T>;template<typename T>B(T,T)->B<T>;
}

 

c++17新概念:主要用来在推断类模板参数时提供推断指引。
(1)隐式的推断指南
           针对类模板A的每个构造函数,都有一个隐式的模板参数推断机制存在,这个机制,被称为隐式的推断指南
            template<typename T>
            A(T,T)->A<T>;
              表达出现->左侧部分内容或者形式时,请推断成->右侧的类型。右侧类型也被称为“指南类型”
                 ->左侧部分:该推断指南所对应的构造函数的函数声明,多个参数之间用,分隔。
                ->右侧部分:类模板名,接着一个尖括号,尖括号中是模板参数名。
            整个推断指南的含义:当用调用带两个参数的构造函数通过类模板A创建相关对象时,请用所提供的构造函数的实参来推断类模板A的模板参数类型,
           一句话:推断指南的存在意义就是让编译器 能够把模板参数的类型推断出来。
            template<typename T>
            A(T,T)->A<double>;
           那么:A aobj1(15, 16);代码行 相当于A<double> aobj1(15, 16);
(2)自定义的推断指南
            _nmsp3::B bobj3{ 15 }; 不报错的原因
                a)类B是聚合类。 是可以通过{}初始化的
                b)B bobj3{ 15 }这种形式正好就相当于调用了类模板B的带一个参数(15)的构造函数,尽管类模板B中实际并不存在构造函数。
                c)因为template<typename T>B(T)->B<T>;推断指南的存在,当调用了类模板B带一个参数的构造函数时,推断出来的类型为B<T>,所以
                   最终推断出来的类型为B<int>类型。
 

当我们定义一个模板类或者模板函数时,有时候编译器可能无法准确地推导模板参数,或者存在多个可能的推导结果,这时候就需要使用推断指南来明确告诉编译器我们期望的推导结果。

举例说明:

假设我们有一个模板类 Pair,用于表示一对值。它有两个模板参数,分别表示这对值的类型。现在我们希望在传入两个参数时,编译器可以自动推导出这两个参数的类型,并实例化 Pair 类。但是,由于模板参数推导的规则,编译器可能无法准确地推导出这两个参数的类型,或者存在多个可能的推导结果。

这时候,我们可以使用推断指南来帮助编译器更准确地推导模板参数。例如:

cppCopy Code
template<typename T, typename U>
class Pair {
public:T first;U second;Pair(T f, U s) : first(f), second(s) {}
};

如果我们使用如下方式创建一个 Pair 对象:

Pair p(5, 3.14);

编译器可能无法准确推导出 Pair 的模板参数类型,因为 5 可以是 intdoublefloat 等类型,而 3.14 可以是 doublefloat 类型。

为了明确告诉编译器我们期望的推导结果,我们可以提供一个推断指南,如下所示:

template<typename T, typename U>
Pair(T, U) -> Pair<T, U>;

这个推断指南告诉编译器,当我们传入两个参数时,应该推导出模板参数类型为 TU,从而实例化 Pair<T, U> 类。

通过使用推断指南,我们可以确保编译器能够正确推导模板参数,从而避免模板实例化过程中可能出现的错误或二义性。

 

template<typename T>
class A
{
public:A(T const& t):s(t) {}T& show() { return s; }
private:T s;
};//  推断指引
A(const char*)->A<std::string>;
A(bool)->A<int>;
A(int)->A<char>;int main()
{A Int{40};  //  input intcout << typeid(Int.show()).name() << endl;  //  output charA Bool{ true };  //  input boolcout << typeid(Bool.show()).name() << endl;  //  output intA str{ "ssssss" };  //  input char[]cout<<typeid(str.show()).name()<<endl;  //  output std::stringreturn 0;
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/28534.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

为什么不建议使用Executors来创建线程池

不建议使用`Executors`类的静态方法(如`newFixedThreadPool`, `newSingleThreadExecutor`, `newCachedThreadPool`等)来创建线程池,主要基于以下几个原因: 1. 隐藏关键配置参数:`Executors`提供的便捷方法通常会隐藏线程池的重要配置参数,比如线程池的大小、工作队列类型…

hmac:Python密码消息签名

前言 HMAC算法可以用于验证信息的完整性,这些信息可能在应用之间传递,或者存储在一个可能有安全威胁的地方。 其基本思路:生成实际数据的一个密码散列,并提供一个共享的秘密密钥。然后使用得到的散列检查所传输或存储的信息,以确定一个信任级别,而不传输秘密密钥。 消息签…

socket:Python网络通信套接字

Socket网络通信套接字 socket库提供了一个底层C API,可以使用BSD套接字接口实现网络通信。它包括socket类,用于处理具体的数据通道,还包括用来完成网络相关任务的函数,如将一个服务器名转换为一个地址以及格式化数据以便在网络上发送。 什么是套接字? 套接字是程序在本地或…

el-upload以及blob自动根据列表名称匹配下载

dom文档<el-row :gutter="20"><el-col :span="16" :offset="0"><el-form-item label-width="120px" label="文件上传"><el-uploadref="upload"class="upload-file-uploader upload-dem…

振弦采集仪在岩土工程监测中的故障排除和维护要点

振弦采集仪在岩土工程监测中的故障排除和维护要点 河北稳控科技振弦采集仪在岩土工程监测中是一种常用的测量设备,通过测量振弦的振动频率来判断土体的力学性质和变形情况。然而,如果振弦采集仪出现故障,则会影响监测工作的正常进行。因此,掌握振弦采集仪的故障排除和维护要…

Mysql-事务的基本特性和隔离级别

0.背景 在数据库中,事务是一组数据库操作,可以将事务操作视为一个基本的工作单元。 1.事务的基本特性 事务的基本特性“ACID” 对于事务呢,就是这一组sql操作,要确保ACID这4个基本特性。 哎,八股文不好背,我记忆方式是:一元吃个(原持隔)原子性(Atomicity):事务中的…

使用pycnblog一键拖拽同步markdown和图片

目录原因解决办法参考链接准备工作配置config.yaml其他设置图片运行 原因本地使用Typora写完文档,上传博客园时,图片不能同步解决办法 参考链接博客园上传markdown文件准备工作下载工具pycnblog安装Python3pip install pyyaml配置config.yaml blog_url: https://rpc.cnblogs.…

blazor优雅的方式导入组件相关的js脚本

基本的组件导入方式为:1 await JsRuntime.InvokeVoidAsync("import", $"XXXXX.js");优雅的组件导入方式:1 await JsRuntime.ImportAsync<DocEditor>();这种优雅一点不难,只需要写一个扩展方法,把他放在任意地方并且导入命名空间,或者放到和项目…