CPP嵌套从属名称与typename

typename与class

在template的声明式中

template< class T>//声明方法1
template< typename T>声明方法2,使用typename 可以暗示参数不一定是一个class类型
使用方法1和方法2意义完全相同。但是涉及嵌套从属名称(nested dependent name)时只能使用关键字typename:

1
2
3
4
5
6
7
8
9
10
template<typename C>
void print1st(const C& container)
{
if(container.size()>1)
{
C::const_iterator iter(container.begin());//局部变量iter是从属名称
int value = * iter;//局部变量value是非从属名称
std::cout<<value;
}
}

从属名称(dependent name):template内出现的名称(示例中的iter)如果相依于某个template参数(示例中的C)的名称。如果从属名称在class内呈嵌套状,则称为嵌套从属名称(nested dependent name)。const_iterator也是类。

非从属名称(non-dependent name):不依赖于任何template参数的名称。

困惑:嵌套从属名称可能导致解析困难:

1
2
3
4
5
template<typename C>
void print1st(const C& container)
{
C::const_iterator* x;//如果const_iterator是类,则x是一个指向const_iterator的指针,但如果const_iterator是一个变量的名称,则是一个相乘动作。
}

C++中一个相关的解析规则:如果解析器在template中遭遇一个嵌套从属名称,便假设这名称不是一个类型,除非你通过放置关键字typename告诉它是

1
2
3
4
5
template<typename C> 
void print1st(const C& container)
{
typename C::const_iterator* x;*//通过放置关键字typename说明const_iterator是类型*
}

也就是说:任何时候当你想要在template中指涉一个嵌套从属类型名称,就必须在紧邻它的前一个位置放置typename关键字作为前缀词。这个规则的例外:

不可以出现在base classes list内的嵌套从属名称之前
不可以出现在member initialization list(成员初值列)中作为base class修饰符

1
2
3
4
5
6
7
template<typename T>
class derived:public base<T>::nested{//此处不可以
public:
explivit derived(int x):base<T>::nested(x){//此处不可以
typename base<T>::nested temp;//此处可以
}
}
  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!
  • Copyrights © 2020-2023 cyg
  • 访问人数: | 浏览次数: