If I work with classes, everything is just fine:
struct Base1 {
int value;
Base1(int value) : value(value) { }
};
struct Test1 : public Base1 {
int getValue() { return value; }
Test1(int value) : Base1(value) { }
};
but with templates scope resolution is needed:
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) { }
};
Without the scope resolution I receive error 'value' was not declared in this scope (gcc compiler used).
Why?
Because the compiler is not aware that
valueis dependent on the template argument. As such, it attempts to resolve it during the first pass (prior to instantiating the template), and fails.The two options are to use the scoping resolution, as you have, or use
this->value. Sincethisis always a dependent name, this will force the evaluation to occur during the second pass.See http://ideone.com/07odY
Edit: And as to the why it needs to be done at all:
While
Test<T>derives fromBase<T>, due to template specialization you could makeBase<std::string>(for example) be totally different than the normalBase<T>, and not have a member namedvalue, or it could be of a different type, or anything. By forcing it to be a dependent name, the compiler is forced to wait until it knows the actual type involved before checking.