你如何理解C ++中的依赖名称?
我通常在模板的上下文中遇到这个术语“从属名称”。 但是,我很less碰到后者。 因此自然想更多地了解依赖名称的概念。
你如何理解它在模板和外部的情况下? 例如批评鼓励!
依赖名称本质上是一个依赖于模板参数的名称。
当使用模板时,模板的定义点和实例化点(即实际使用模板的位置)之间有区别。 取决于模板的名称在实例化之前不会被绑定,而在定义点不会被绑定的名称。
一个简单的例子是:
template< class T > int addInt( T x ) { return i + x.toInt(); }
如果我的声明或定义需要出现在上面给出的定义之前 ,因为i
不依赖于模板参数T
并因此被限定在定义点。 as-yet-unknown-type x
variables的toInt
成员的定义只有在addInt
函数实际用在某个地方之前才会出现,因为它是一个独立的名字(从技术上讲,实例化的地方被认为是最接近的封闭的全局或名称空间范围就在使用点之前,所以它必须在此之前可用)。
依赖名称的特点是依赖于模板参数。 微不足道的例子:
#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; }
编辑 :正如我在下面的评论中所提到的,这是一个关于使用从属名称的相当频繁的特殊情况的例子。 有时,使用依赖名称的规则并不是人们可能本能的期望。
例如,如果你有一个从依赖类派生的依赖类,但是在基类中的一个名称显然不依赖于模板的范围内,你可能会得到如下的编译器错误。
#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; }
发生此错误是因为编译器不会在基类模板中查找name
,因为它不依赖于T
,因此它不是一个独立的名称。 修复的方法是使用this
或明确告诉相关的基类模板:
std::cout << "T: " << this->data << std::endl; //Ok now. std::cout << "T: " << Dependent<T>::data << std::endl; //Ok now.