C++的嵌套依赖别名(typename的用法)

看了很多遍,还是记录一下

1、在模板声明时typename和class是等价的

template<class T> class Widget; // uses "class"
template<typename T> class Widget; // uses "typename"

两面的两句等价

2、什么情况下必须放typename?

template<typename C>
void print2nd(const C& container)
{
    C::const_iterator *x; //①
    ...
}

此时的编译器会纠结:const_iterator是一个什么东西?const_iterator是模板参数C内的一个static变量?x是一个全局变量?
再或者:const_iterator是模板参数C内部的一个typedef。假设模板参数C最后用Class_C来实例化,Class_C类似这样:

class Class_C{
	typedef int const_iterator;
	...
}

那上面的例子中的语句①就是声明一个指向int类型的指针x,语句①转化过来就是这样:

int *x;

程序员是不能让编译器纠结的,编译器纠结的后果是:报错。程序员嘛,就debug吧。

所以此时我们应该告诉编译器const_iterator是模板参数C里面的一个类型。即在C的前面加上typename就可以了,像这样:

template<typename C>
void print2nd(const C& container)
{
    typename C::const_iterator * x; //①
    ...
}

3、总结一下上面的用法

a、模板内出现的名称如果依赖于某个模板参数,称之为从属名称(dependent name)。如果从属名称在class内呈嵌套状,我们称为嵌套从属名称(nested dependent name)。距离如下:

template<typename C>
void print(const C & container)
{
    C::const_iterator iter(container.begin());
    cout << *iter << endl;
    int value = *iter;
    return;
}
  • 在上述代码中,我的理解C就是一个从属名称。假如我们在函数被使用了类似 C inst_c; 这样的语句,inst_c就是从属于C;
  • 同理,value的类型是语言内置类型,不依赖于任何模板参数,因此被称为 非从属名称;
  • C++编译器在面对从属名称时,如果此时该从属名称又嵌套了其他类型,如此处的 iter就是C::const_iterator类型,这里的C::const_iterator 称为嵌套从属类型名称(嵌套于C类型,从属于模板参数C)。

b、再来看一个例子:

template<typename C> // typename allowed (as is "class")
void f(const C& container, // typename not allowed
		typename C::iterator iter); // typename required

上述的C并不是嵌套从属类型名称 (它并非嵌套与任何“取决于模板参数”的东西内),所以声明container时并不需要以typename为前导。
但C::iterator是个嵌套从属类型名称,所以必须以typename为前导。

c、说人话
使用某个模板类里面typedef的类型时,如果这个类型与模板参数C相关,就需要使用typename。
即这样的形式:
y(C)::iterator it;
这样的语句前面就需要前置typename;

参考:
[1] https://blog.csdn.net/gatieme/article/details/50946005
[2] https://blog.csdn.net/xuqingict/article/details/24884811

[3] C++模板沉思录(上)

  • 9
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值