3

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

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 编译器)。为什么?

4

2 回答 2

6

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

这两个选项是使用范围分辨率,就像你一样,或者使用this->value. 由于this始终是从属名称,因此这将强制在第二遍期间进行评估。

http://ideone.com/07odY

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

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

于 2012-05-23T15:07:20.203 回答
3

因为没有其他方法可以告诉编译器(因为它没有在Tests 主体中定义)这value是一个依赖名称。您正在强迫编译器说“好吧!当我说type这样一个成员时,请相信我。”valueT

于 2012-05-23T15:02:27.190 回答