我通常在模板的上下文中遇到这个术语"依赖名称".但是,我很少接触后者.因此,自然希望更多地了解依赖名称的概念.
您如何在模板和其他模板的上下文中理解它?这个例子受到了极大的鼓励
Lea*_*elo 13
依赖名称的特征在于对模板参数的依赖性.琐碎的例子:
#include <vector>
void NonDependent()
{
//You can access the member size_type directly.
//This is precisely specified as a vector of ints.
typedef std::vector<int> IntVector;
IntVector::size_type i;
/* ... */
}
template <class T>
void Dependent()
{
//Now the vector depends on the type T.
//Need to use typename to access a dependent name.
typedef std::vector<T> SomeVector;
typename SomeVector::size_type i;
/* ... */
}
int main()
{
NonDependent();
Dependent<int>();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编辑:正如我在下面的评论中提到的,这是一个关于使用依赖名称的特殊情况的例子,这种情况经常出现.有时,管理依赖名称使用的规则并不是人们本能地期望的.
例如,如果您有一个从依赖类派生的依赖类,但在一个范围内,其中基类的名称显然不依赖于模板,您可能会得到编译器错误,如下所示.
#include <iostream>
template <class T>
class Dependent
{
protected:
T data;
};
template <class T>
class OtherDependent : public Dependent<T>
{
public:
void printT()const
{
std::cout << "T: " << data << std::endl; //ERROR
}
};
int main()
{
OtherDependent<int> o;
o.printT();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
发生此错误是因为编译器不会data在基类模板内查找,因为它不依赖于T,因此,它不是依赖名称.修复方法是使用this或明确告知依赖基类模板:
std::cout << "T: " << this->data << std::endl; //Ok now.
std::cout << "T: " << Dependent<T>::data << std::endl; //Ok now.
Run Code Online (Sandbox Code Playgroud)
Tro*_*our 11
从属名称本质上是一个依赖于模板参数的名称.
使用模板时,模板的定义点和实例化点之间存在区别,即实际使用模板的位置.依赖于模板的名称在实例化之前不会被绑定,而名称不会在定义点处被绑定.
一个简单的例子是:
template< class T > int addInt( T x )
{
return i + x.toInt();
}
Run Code Online (Sandbox Code Playgroud)
其中声明或定义i需要出现在上面给出的定义之前,因为i它不依赖于模板参数T,因此在定义点上受到约束.在定义toInt了的尚未未知类型的成员x变量只出现前的addInt功能实际上是用的地方,因为它是一个从属名称(技术上实例化的点作为最近刚刚之前封闭全局或命名空间范围使用点,因此必须在此之前可用.