为什么需要在模板继承中使用范围解析

Why do I need to use scope resolution in template inheritance?

本文关键字:使用范围 继承 为什么      更新时间:2023-10-16

如果我使用类,一切都很好:

struct Base1 {
  int value;
  Base1(int value) : value(value) { }
};
struct Test1 : public Base1 {
  int getValue() { return value; }  
  Test1(int value) : Base1(value) { }
};

但使用模板需要范围解析:

template <typename T>
struct Base {
  T value;
  Base(T value) : value(value) { }
};
template <typename T>
struct Test : public Base<T> {
  typedef Base<T> parent;
  T getValue() { return parent::value; }  // why do I need to use parent:: here?
  Test(T value) : parent(value) { }
};

如果没有范围解析,我会收到错误'value' was not declared in this scope(使用 gcc 编译器(。为什么?

因为编译器不知道value依赖于模板参数。 因此,它会尝试在第一次传递期间(在实例化模板之前(解决它,但失败。

这两个选项是使用范围分辨率(如您拥有的那样(或使用 this->value 。 由于this始终是依赖名称,这将强制在第二次传递期间进行评估。

请参阅 http://ideone.com/07odY

编辑:至于为什么需要这样做:

虽然Test<T>派生自Base<T>,但由于模板专用化,你可以使Base<std::string>(例如(与普通Base<T>完全不同,并且没有一个名为value的成员,或者它可以是不同类型的,或者任何东西。 通过强制将其作为依赖名称,编译器被迫等到知道所涉及的实际类型后再进行检查。

因为没有其他方法可以告诉编译器(因为它没有在Test体内定义(value是一个依赖名称。您正在强迫编译器说"好吧!当我说有这样一个成员value类型T时,请相信我。