2025年typename的两种用法

typename的两种用法typename 有两种用法 第一种用于声明模板时 表示模板类型参数 如下所示 在用于模板声明时 typename 和 class 等价 具有同等含义 template lt typename T gt class MyClass 等价于 template lt class T

大家好,我是讯享网,很高兴认识大家。

typename有两种用法,第一种用于声明模板时,表示模板类型参数,如下所示。在用于模板声明时,typename 和 class 等价,具有同等含义。

template<typename T> class MyClass; // 等价于 template<class T> class MyClass; 

讯享网

typename的第二种用法,用于表示一个类内所指的类型为一个 “class” 类型(内置类型、自定类型),而非其他(变量、函数类型)。更一般的说法是,typename 用来告诉编译器类中的嵌套名称表示的是一个类型。看下面一个例子。

讯享网class MyCls { 
    public: using value = int; }; template<typename T> void func(T t) { 
    typename T::value v = 10; std::cout << v << std::endl; } void test_MyCls() { 
    MyCls m; func(m); } int main() { 
    test_MyCls(); } 

我的编译环境为: Ubuntu 20.04 + g++ (GCC) 11.3.0。编译上述代码,能正确编译通过。
在这里插入图片描述
讯享网
若将 func 中的 typename 关键字去掉,则会编译失败,编译结果如下所示:
在这里插入图片描述

编译报错的主要原因是,在模板实例化的过程中,T::value 没有被解析为一个类型,如编译结果中红色圈出的部分所示。但可能会存在这样一种疑问,在上面的示例中,模板参数T在模板实例化的过程中解析为 MyCls,而 MyCls::value 在 MyCls 中被声明为 int 的别名,因此 T::value 被实例化为 MyCls::value 后表示的应该就是一个类型。这样直觉的理解看似没问题,但违反了C++中的模板解析规则。在模板实例化之前,会先对语法进行解析,当解析到 T::value 时,T还没被实例化为一个具体的类型,因此 T::value 可能表示的是一个类型,也可能表示的是一个 static 变量,也可能是一个全局的变量,因此 T::value 就存在了歧义,因此编译器编译不通过。为了解决这种起义,C++中规定,当使用类中的嵌套类型时,需要使用 typename 进行声明。


在 《Effective C++》的条款42中,对类中的嵌套类型的描述摘录如下。

template 内出现的名称如果相依于某个template参数,称之为从属名称(dependent names)。如果从属名称在 class 内呈嵌套状,我们称它为从属嵌套名称(nested dependent name)。

因此有了规则 “typename 必须作为嵌套从属类型名称的前缀词”。

“typename 必须作为嵌套从属类型名称的前缀词” 这一规则的例外是,typename 不可以出现在 base classes list 内的嵌套从属名称之前,也不可以在 member initialization list 中作为 base class 修饰符。

在这里插入图片描述

小讯
上一篇 2025-02-09 08:26
下一篇 2025-04-11 16:07

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/70400.html