【C++】深入解析C++嵌套依赖类型与typename关键字

什么是嵌套依赖类型?

嵌套依赖类型(Nested Dependent Type)是指在一个模板中,一个类型名称依赖于模板参数,并且是该模板参数内部的嵌套类型。

具体来说,当一个类型满足以下两个条件时,它就是嵌套依赖类型:

  1. 它嵌套在另一个类型内部(如 Container::iterator

  2. 外层类型依赖于模板参数(如 T::inner_typeContainer<T>::iterator

比如:

template <class T>
void print_list(const list<T>& l)
{typename list<T>::const_iterator it = l.begin();    // 这里 list<T> 依赖于模板参数 Twhile (it != l.end()){cout << *it << " ";++it;}cout << endl;
}

list<T>::const_iterator 就是一个嵌套依赖类型,因为:

  • const_iterator 嵌套在 list<T> 内部

  • list<T> 依赖于模板参数 T

为什么需要 typename 关键字?

C++ 编译器在解析模板时,需要知道一个依赖名称是类型还是值。由于模板可能被特化,编译器在实例化之前无法确定依赖名称的性质。

使用 typename 关键字可以明确告诉编译器:"这个依赖名称是一个类型"。

其他需要使用 typename 的情况

除了在函数内部声明嵌套依赖类型的变量外,还有以下几种情况需要使用 typename

        1. 作为函数返回类型

template <class T>
typename T::value_type get_first(const T& container) {return *container.begin();
}

        2. 作为函数参数类型

template <class T>
void process_element(typename T::element_type elem) {// 处理元素
}

        3. 在模板中声明成员变量类型

template <class Container>
class Wrapper {
public:typename Container::value_type first_element; // 使用 typename
};

        4. 使用用模板模板参数中的嵌套类型

template <template <class> class Container, class T>
void print_size(const Container<T>& c) {typename Container<T>::size_type s = c.size(); // 使用 typenamecout << s << endl;
}

        5. 在继承中指定基类类型

template <class T>
class Derived : public typename T::BaseType { // 使用 typename// ...
};

不需要使用 typename 的情况

以下情况不需要使用 typename

        1. 非依赖类型

template <class T>
void func() {std::string s; // 不需要 typename,因为 std::string 不依赖于 Tint i;         // 不需要 typename
}

        2. 基类列表和成员初始化列表

template <class T>
class Derived : public T::Nested { // 这里不需要 typename
public:Derived() : T::Nested() {} // 这里也不需要 typename
};

代码示例

#include <iostream>
#include <vector>
#include <list>
using namespace std;// 1. 函数返回类型中使用 typename
template <class Container>
typename Container::value_type get_first(const Container& c) {return *c.begin();
}// 2. 函数参数中使用 typename
template <class Container>
void print_element(typename Container::value_type elem) {cout << elem << " ";
}// 3. 类模板中使用 typename
template <class Container>
class ContainerInfo {
public:typedef typename Container::value_type value_type; // 使用 typenametypedef typename Container::iterator iterator;     // 使用 typenamestatic void print_info() {cout << "Container value_type: " << typeid(value_type).name() << endl;}
};int main() {vector<int> vec = {1, 2, 3};list<double> lst = {1.1, 2.2, 3.3};// 测试函数返回类型中的 typenamecout << "First element of vector: " << get_first(vec) << endl;cout << "First element of list: " << get_first(lst) << endl;// 测试类模板中的 typenameContainerInfo<vector<int>>::print_info();ContainerInfo<list<double>>::print_info();return 0;
}

总结

  • 嵌套依赖类型是指依赖于模板参数的嵌套类型

  • 使用 typename 关键字告诉编译器某个依赖名称是类型而不是值

  • 在函数返回类型、参数类型、变量声明等地方都可能需要使用 typename

  • 只有在处理依赖类型时才需要使用 typename,非依赖类型不需要

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

管网信息化监测主要的内容

管网信息化监测是指通过现代信息技术手段对管网系统进行实时监控和数据采集的管理方式。其背景源于城市化进程加快以及基础设施建设规模不断扩大&#xff0c;传统的管网管理模式已无法满足现代化需求。管网信息化监测主要内容包括以下几个方面&#xff1a;█管网运行状态监测&a…

数据泄露代价千万,PII 保护你真的做对了吗?

一、PII—数据隐私的核心概念解析 在大多数数据隐私法律中,可识别个人信息(PII, Personally Identifiable Information)是指任何可以用来识别个人身份的信息。然而,PII 的定义并非由单一法律统一规定,不同国家和地区的法律对其定义略有差异: 各国对 PII 的定义 美国 20…

【数据结构】八大排序之快速排序:分而治之的艺术

文章目录快速排序1.hoare版本算法优化三数取中法小区间优化完整代码如下算法分析时间复杂度空间复杂度2.前后指针法排序过程3.非递归&#xff08;栈模拟&#xff09;实现思路总结快速排序 快速排序是Hoare于1962年提出的一种二叉树结构的交换排序方法&#xff0c;其基本思想为…

在ROS中获取并发布UBS式传感器的温湿度

哈喽大家好&#xff0c;我是钢板兽&#xff01; 今天更新一篇和ROS相关的文章&#xff0c;有个项目需求是在ROS中获取并发布UBS式传感器的温湿度&#xff0c;我使用的温湿度传感器简介如下&#xff1a;DL11- MC-S1 温湿度传感器通过USB 接口采用标准MODBUS RTU 协议通信&#x…

【图论】 Graph.jl 操作汇总

文章目录图论的集合类操作Base.getindexBase.intersectBase.joinBase.reverseBase.reverse!Base.sizeBase.sumBase.sumBase.union图生成与转换Graphs.cartesian_productGraphs.complementGraphs.compute_shiftsGraphs.crosspathGraphs.differenceGraphs.egonetGraphs.induced_s…

【链表 - LeetCode】146. LRU 缓存

146. LRU 缓存 题解&#xff1a; class LRUCache {list<pair<int,int>>v;unordered_map<int,list<pair<int,int>>::iterator>idx;int capacity; public:LRUCache(int capacity):capacity(capacity){}int get(int key) {if(idx.count(key) 0) …

Elasticsearch vs Solr vs OpenSearch:搜索引擎方案对比与索引设计最佳实践

Elasticsearch vs Solr vs OpenSearch&#xff1a;搜索引擎方案对比与索引设计最佳实践 随着大数据和实时分析需求的爆发&#xff0c;搜索引擎已成为许多业务系统中的核心组件。本篇文章将从“技术方案对比分析型”角度切入&#xff0c;重点比较三大主流搜索引擎&#xff1a;El…

光颉科技)Viking)的CS25FTFR009 1225 0.009R/9mR 3W电阻介绍-华年商城

“**华年商城”**小编为您介绍&#xff1a;光颉科技&#xff08;Viking&#xff09;的CS25FTFR009 1225 0.009R/9mR 3W电阻 光颉CS25FTFR009合金电阻&#xff1a;0.009Ω/9mΩ 3W 1%精密采样电阻 光颉科技&#xff08;Viking&#xff09;的CS25FTFR009是一款高性能的电流检测电…

港科大开放世界长时域具身导航!LOVON:足式机器人开放词汇目标导航

作者&#xff1a;Daojie Peng1^{1}1, Jiahang Cao1,2^{1,2}1,2, Qiang Zhang1,2^{1,2}1,2, Jun Ma1,3^{1,3}1,3单位&#xff1a;1^{1}1香港科技大学&#xff08;广州&#xff09;&#xff0c;2^{2}2北京人形机器人创新中心&#xff0c;3^{3}3香港科技大学论文标题&#xff1a;L…

【前端教程】JavaScript 数组对象遍历与数据展示实战

在前端开发中&#xff0c;处理数组和对象是日常工作的基础。无论是篇文章将通过一个具体案例&#xff0c;详细讲解如何使用JavaScript遍历包含对象的数组&#xff0c;并将数据以清晰的格式展示在页面上。我们会从基础语法开始&#xff0c;逐步优化代码&#xff0c;最终实现一个…

无重复字符的最长子串,leetCode热题100,C++实现

题目来源&#xff1a;leetCode 3. 无重复字符的最长子串 - 力扣&#xff08;LeetCode&#xff09; 给定一个字符串 s &#xff0c;请你找出其中不含有重复字符的 最长 子串 的长度。 解法 class Solution { public:int lengthOfLongestSubstring(string s) {unordered_set<…

卷积神经网络中1×1卷积的作用

part I &#xff1a;来源part II &#xff1a;应用part III &#xff1a;作用&#xff08;降维、升维、跨通道交互、增加非线性&#xff09;part IV &#xff1a;从fully-connected layers的角度理解一、来源&#xff1a;[1312.4400] Network In Network &#xff08;如果11…

VMware设置Ubuntu虚拟机桥接模式完整教程

VMware 设置 Ubuntu 虚拟机桥接模式完整教程 下面是一个详细的、避免出错的 VMware Ubuntu 桥接模式设置教程&#xff0c;包含常见问题的解决方案。 准备工作 确保宿主机&#xff08;Windows 11&#xff09;已连接到网络&#xff08;有线或无线&#xff09;确认您有管理员权限关…

浅析NVMe协议:DIF

文章目录概述DIF数据格式盘片支持DIFFormatPILPIMSETLBAF协议命令DIF支持PRACTPRACT0PRACT1PRCHK相关参考概述 NVMe协议将DIF信息作为元数据的一部分进行携带。 DIF数据格式 DIF的PI由多个字段组成&#xff0c;包括&#xff1a; Guard字段&#xff1a;基于逻辑块数据计算的C…

【观成科技】蔓灵花User下载者加密通信分析

概述2025年5月7日&#xff0c;蔓灵花&#xff08;BITTER&#xff09;组织针对巴基斯坦电信公司工作人员发起钓鱼邮件攻击&#xff0c;投递伪装为安全简报的恶意邮件&#xff0c;附件为IQY类型的Web查询文件。该文件在用户执行后通过HTTP协议获取远程CMD指令并执行&#xff0c;进…

Redis 保证数据不丢失

Redis 保证数据不丢失&#xff08;或最大限度减少丢失&#xff09;的核心是通过 持久化机制 结合 合理的配置策略 实现的。具体方案如下&#xff1a;一、核心&#xff1a;开启 Redis 持久化&#xff08;防止进程崩溃丢失数据&#xff09;Redis 提供两种持久化方式&#xff0c;可…

NUMA/SNC 4种组合下Stream+MLC性能对决:双路服务器BIOS调优全攻略

关于调整 BIOS NUMA 与 SNC 选项的 Stream / MLC 性能测试总结一、测试背景与目的在现代多路 Intel Xeon 服务器上&#xff0c;NUMA&#xff08;Non-Uniform Memory Access&#xff09;与 SNC&#xff08;Sub-NUMA Clustering&#xff09;是两项决定内存访问延迟与带宽的关键 B…

Java-113 深入浅出 MySQL 扩容全攻略:触发条件、迁移方案与性能优化

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; &#x1f680; AI篇持续更新中&#xff01;&#xff08;长期更新&#xff09; AI炼丹日志-31- 千呼万唤始出来 GPT-5 发布&#xff01;“快的…

Kafka Connect + Streams 用到极致从 CDC 到流处理的一套落地方案

关键目标&#xff1a; 零丢失&#xff1a;端到端 Exactly Once&#xff08;Source 端事务 Streams exactly_once_v2 Sink DLQ&#xff09;。低延迟&#xff1a;Producer 端批量压缩 Streams 缓存 合理 poll/commit 间隔。可恢复&#xff1a;Connect/Streams 的 rebootstrap…

# `std::basic_istream`总结

std::basic_istream总结 文章目录std::basic_istream总结概述常用类型定义全局对象核心成员函数1. 格式化输入2. 非格式化输入3. 流定位4. 其他功能继承的功能来自 std::basic_ios状态检查状态管理来自 std::ios_base格式化标志流打开模式特点说明例子std::basic_istream全面用…