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

C++ 泛型编程之补充(class 和typename)

目录

1.class 和 typename 可互换

1.1 template 和 template 在模板参数列表中完全一样,可以互换使用。

2.什么时候 class 和 typename 不一样?

2.1  嵌套依赖类型 时必须用typename

重点说明:

2.2 普通作用域(不能互换,不能加 typename)


在 C++ 模板编程中,classtypename 在某些情况下可以互换使用,而在某些情况下不能互换,甚至 typename 是必须的。下面是更详细的解释和示例:

1.classtypename 可互换

1.1 template<class T>template<typename T> 在模板参数列表中完全一样,可以互换使用。

template<class T>    // 合法
void Print1(T value) { cout << value << endl; }

template<typename T> //  也是合法
void Print2(T value) { cout << value << endl; }

int main()
{
    Print1(42);   // T = int
    Print2(3.14); // T = double
}

2.什么时候 classtypename 不一样?

2.1  嵌套依赖类型必须用typename

虽然 template<class T>template<typename T> 一样,但 typename嵌套依赖类型必须用!

必须使用 typename 关键字,以告诉编译器这是一个类型,T模板参数,编译器在解析模板时 并不知道 T::value_type 是类型还是变量typename 关键字告诉编译器:T::value_type 一定是一个类型。例如:

template <typename T>
class Outer {
public:
    using NestedType = typename T::Type;  // 必须加 typename
};

 如果 T::Type 依赖于模板参数 T,那么编译器在第一遍解析时无法确定 T::Type 是一个类型还是一个变量。因此,需要显式使用 typename 关键字。

下面是一个完整的代码示例以及代码分析:

template <typename T>
struct Wrapper {
    using Type = typename T::value_type; // typename 不能省略
};

struct MyType {
    using value_type = int;
};

int main() {
    Wrapper<MyType>::Type a = 10; // 正确
    return 0;
}

重点说明:

第一步:理解 MyType:MyType 是一个结构体(struct),using value_type = int;value_type 成为 int 的别名,这意味着 MyType::value_type 等价于 int

第二步:理解 Wrapper<T>,

  • 这里 Wrapper模板类T 是一个 模板参数
  • using Type = typename T::value_type;
    • T::value_type 依赖于模板参数 T
    • typename 不能省略,因为 T::value_type依赖类型(编译器在第一遍解析时不确定它是类型还是变量)。
    • Type 变成了 T::value_type 的别名。
    • 如果 T = MyType,那么展开后等价于:
struct Wrapper<MyType> {
    using Type = typename MyType::value_type; // 即 using Type = int;
};
//最终

Wrapper<MyType>::Type == MyType::value_type == int

第三步main() 函数 :

  • Wrapper<MyType>::Type 等价于 int
  • a 的类型就是 int,所以 a = 10; 是合法的。
int main() {
    Wrapper<MyType>::Type a = 10; // 正确
    return 0;
}

2.2 普通作用域(不能互换,不能加 typename

非模板上下文(普通作用域)中,不允许使用 typename,也不允许用 class 代替 typename

struct MyType {
    using value_type = int;
};

int main() {
    typename MyType::value_type a = 10; //  错误:非模板作用域不能使用 typename
    return 0;
}

相关文章:

  • 【复习】Java集合
  • Vue2是如何利用Object.defineProperty实现数据的双向绑定?
  • 第十一章: vue2-3 生命周期
  • 《Operating System Concepts》阅读笔记:p62-p75
  • Uptime Kuma实现业务接口自定义逻辑监控
  • MySQL的数据类型
  • Java 虚拟机(JVM)方法区详解
  • C++ 设计模式-备忘录模式
  • 网页转EXE 网页变EXE 网页封装EXE
  • HTTPS 通信流程
  • 《算法基础入门:最常用的算法详解与应用(持续更新实战与面试题)》
  • 进程线程的创建、退出、回收
  • 2025年02月21日Github流行趋势
  • Android级联选择器,下拉菜单
  • 33. 搜索旋转排序数组(LeetCode热题100)
  • 【智能客服】ChatGPT大模型话术优化落地方案
  • Repeated Sequence
  • 基于STM32单片机的智能蔬菜大棚温湿度监测系统设计
  • elabradio入门第八讲——帧同步技术
  • 伯克利 CS61A 课堂笔记 12 —— Syntax
  • 域名申请通过了网站怎么做/百度刷排名seo
  • 买公司的网站建设/郑州网络推广排名
  • 正规做网站/重庆关键词自动排名
  • 网站控制面板中设置目录权限/成人本科
  • 网站名称及网址/南昌seo实用技巧
  • 个人网站的基本风格是/网络营销的营销策略