如果我使用课程,一切都很好:
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编译器)。
为什么呢?
答案 0 :(得分:6)
因为编译器不知道value
依赖于模板参数。因此,它尝试在第一次传递期间(在实例化模板之前)解决它,并且失败。
这两个选项是使用范围分辨率,或者使用this->value
。由于this
始终是从属名称,因此这将强制在第二次传递期间进行评估。
编辑:至于为什么需要完成它:
虽然Test<T>
来自Base<T>
,但由于模板专精化,您可以使Base<std::string>
(例如)与普通Base<T>
完全不同,并且没有成员名为value
,或者它可以是不同类型或任何类型。通过强制它成为一个从属名称,编译器必须等到它在检查之前知道所涉及的实际类型。
答案 1 :(得分:3)
因为没有其他方法可以告诉编译器(因为它没有在Test
体内定义),value
是一个从属名称。你强迫编译器说“好的!相信我,当我说 这样的成员value
为T
类型时。”